0

In a script, I have:

CMD='/usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \; '

MD5=$("${CMD}")

But the script gives the error:

-bash: /usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \; : No such file or directory

However the contents of the $CMD work when typed verbatim at the command line, i.e.

/usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \;

Correctly generates a list of md5 hashes.

I've tried everything I can think of, including escaping the backslash and semicolon in the string, but can't seem to get it to work.

I've also tried invoking the command with backticks, which doesn't change the result.

What am I doing wrong ?

Anthon
  • 79,293
tmark
  • 1
  • CMD=$(/usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \; ) is the proper way of doing command substitution. If you are looking for the old way, they are not straight ticks, but backticks, like the one right under the ~ character on most US type keyboards, but try using the method I suggested. It is the proper way of doing it. Backticks are being deprecated. – MelBurslan Mar 29 '16 at 14:05

2 Answers2

1

The whole string between the single quotes (including spaces) is sought as the binary/script to execute by bash, exactly as the error indicates. I.e. this doens't try to start /usr/bin/find with arguments it tries to start /usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \;.

Anthon
  • 79,293
0

You used "${CMD}" inside double quote, so the result from expanding $CMD was not performed field splitting (and also filename expansion), the whole string /usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \; is considered as the command to run. There's no command named like that, so the shell reported No such file or directory error.

Because you use bash, it's better to use an array instead:

$ CMD=( /usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \; )
$ "${CMD[@]}"

or POSIXly, use "$@":

$ set -- /usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \;
$ "$@"

In your first case, you can use $CMD without double quote, but it's not recommended and easily fail. At least you need to set -f before running $CMD.

cuonglm
  • 153,898