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.

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

2 Answers 2

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 

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.