コマンド用の Bash 拡張である ${@}

コマンド用の Bash 拡張である ${@}

親スクリプトがあります

while read cmd 
do
  nohup ./script ${cmd[@]} &>> log &
done < ~/list 

この添え字を実行してください

while true
do 
  eval "${CMD[@]}"
  #${CMD[@]}
  #./panic
done

このコマンドのリストに

node ~/www/splash/app.js
node ~/www/splash-two/app.js

添え字が呼び出されると、eval ${CMD[@]}何の不満もなく期待どおりにコマンドが実行されますが、evalを削除して${CMD[@]}コマンドを実行しようとするとエラーが発生します。

Error: Cannot find module '/home/rumplefraggle/SYS/RABBOT/~/www/splash/app.js'

今、これがノードコマンドに関連している可能性があると考えて、
ls ~
コマンドで実行しようとしましたが、見つかりません~エラーが発生しました。

実行せずにエコーすると、期待${@}どおりに拡張されます。

または、コマンドを下付き文字に手動で挿入すると、期待どおりに機能します。

evalなぜ動作するのか理解できず、単にコマンドで実行しても${@}機能しません。${@}拡張できない原因は何ですか~

${@}ノードを使用するときにコマンドにディレクトリ名を追加するのはなぜですか?

答え1

これはチルダ拡張によるものです。 eval はチルダを拡張し、ホームディレクトリのフルパスに置き換えます。これがない場合、コマンドは渡されたリテラルチルダを使用し、存在しない相対パスを使用しようとします。

$ echo ~
/home/chris
$ echo "~" 
~
$ eval 'echo ~' 
/home/chris 

答え2

見積もりが必要です:"${cmd[@]}"

引用符がない場合、配列のすべての要素は単一の文字列に圧縮されます。引用符を使用すると、各要素が個別に正しく処理されます。

~から手動:

もし下付き文字is‘@’または場合、‘*’この用語は配列のすべてのメンバーに拡張されます。名前。これらの下付き文字は、単語が二重引用符で囲まれている場合にのみ異なります。単語を二重引用符で囲んだ場合[...] ${name[@]}名前の各要素を別々の単語に展開します。

関連情報