/usr/bin/find コマンドの置換と併用すると、呼び出しは機能しません。

/usr/bin/find コマンドの置換と併用すると、呼び出しは機能しません。

スクリプトには次のものがあります。

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

MD5=$("${CMD}")

しかし、スクリプトでエラーが発生します。

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

ただし、コマンドラインにそのまま入力すると、$ CMDの内容が機能します。

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

md5 ハッシュリストを正しく生成します。

文字列でバックスラッシュやセミコロンを避けることを含め、私が考えることができるすべてを試しましたが、うまく動作しないようです。

また、バックティックを使ってコマンドを呼び出しましたが、結果は変わりませんでした。

私は何が間違っていましたか?

答え1

単一引用符(スペースを含む)の間の文字列全体は、エラーが示すものとまったく同じように、bashが実行するバイナリ/スクリプトから取得されます。つまり、/usr/bin/find起動したいパラメータで起動しようとしません/usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \;

答え2

二重引用符で使用したため、"${CMD}"拡張結果は実行されませんでした。$CMDフィールド分割(そしてファイル名拡張子)、文字列全体が/usr/bin/find /etc -type f -exec /usr/bin/md5sum {} \;実行されるコマンドとして処理されます。そのような名前付きコマンドがないため、シェルが報告します。そのファイルやディレクトリはありません。間違い。

以下を使用するので、配列を使用することをお勧めしますbash

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

または、POSIXlyは次のものを使用します"$@"

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

最初のケースでは$CMD二重引用符なしで行うことができますが、推奨しない、失敗しやすい。少なくともset -f実行する前にこれを行う必要があります$CMD

関連情報