4

I run a find command to search files with a name containing perl:

find /tmp -name '*perl*'
/tmp/perl.pl
/tmp/run-perl-stage.pl

But when I set the perl name in a variable PARAMETER and run the find command again then I do not get any results! How to run the find command with $PARAMETER?

PARAMETER=perl
find /tmp -name '*$PARAMETER*'                 

does not get any results.

find /tmp -name '*\$PARAMETER*'

does not get any results.

  • 2
    Yet another classic quoting issue: no variable expansion is performed inside single-quoted strings. Change the single quotes to double quotes. – manatwork Mar 7 '13 at 13:57
  • yes this is the solution thx – yael Mar 7 '13 at 13:59
  • @manatwork looks like an answer – jordanm Mar 7 '13 at 15:21
  • @jordanm, still looking for a suitable duplicate. Can't believe I found no suitable answer for such frequent mistake. – manatwork Mar 7 '13 at 15:26
3

You need to use double quotes, not single quotes.

Inside single quotes '…', every character is interpreted literally. The only character that is treated specially is the single quote character, which ends the literal string.

Inside double quotes "…", the following characters are treated specially:

  • " (double quote) ends the quoted string.
  • $ (dollar) is expanded. It can start a variable substitution or a command substitution or an arithmetic expression: "$PARAMETER", "${PARAMETER}", "${PARAMETER%/*}", "$(somecommand)", $((x+2)), etc.
  • ` (backquote) is expanded. It's an alternate form of command substitution that's hard to use when you have special characters in the nested command: `foo` is like $(foo) but trickier to get right in complex cases.
  • In interactive shells, ! may trigger history expansion.
  • \ (backslash) quotes the next character, but only if it's one of the characters in this list: with other characters, the backslash remains. For example, "foo\$\bar" is equivalent to 'foo$\bar'. As an exception, a backslash-newline sequence is ignored: the backslash eats up the following newline character.

A consequence of that is that you can't have a single quote inside a single-quoted string. To work around that, you can string parts together: echo 'Here'\''s a string with a single quote' passes one argument to echo which is expressed in three parts, two single-quoted strings with \' (expanding to a single single quote) in between.

Since you want variable substitution to happen, use double quotes:

find /tmp -name "*$PARAMETER*"

By the way, there's a difference between "$PARAMETER" and $PARAMETER. With double quotes, the shell looks up the value of PARAMETER and expands that string onto the command line. Without quotes, the value of PARAMETER is interpreted as a whitespace-separated list of wildcard patterns. This is almost never desirable, so always put double quotes around variable and command substitutions.

0

First, never use upper case variable in bash, it may conflict with existing system variables.

Secondly, for your problem, you can do it like this (If you still want single quote, instead of double ones),

param='*perl*'
find /tmp/ -name $param

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.