'eval'は、次のコマンドのリダイレクトされた部分にシェルを適用しますか?

'eval'は、次のコマンドのリダイレクトされた部分にシェルを適用しますか?

evalコマンドと一緒に使用すると、evalコマンドのリダイレクト部分にシェルが2回適用されますか?

リダイレクトのファイル名にスペースが含まれていると仮定すると、すべてのeval解析、シェル拡張、およびトークン化フェーズが複数回適用されると、ファイル名は2番目のトークン化フェーズで2つの単語に分割されます。

eval次の例は、次のコマンドのリダイレクト部分にシェルが2回適用されないため、ファイル名が2つの単語に分割されないことを意味しますか?

$ filename="my file"
$ eval "cat" < "$filename"
hi

ベストアンサー1

提供された例で唯一のことは、evalリダイレクトcatが外部で発生evalし、ファイルがコマンドの標準入力として提供されることですeval "cat"

1つの変形は、単一引用符を使用してリダイレクトを含むコマンド全体を引用することです。

$ eval 'cat < "$filename"'
hi

evalリダイレクトと変数名を含む完全な文字列が取得されるため、変数の拡張だけでなく、スペースを含む必須ファイル名参照も実行されます。これはまだ動作します。

別のオプションは、文字列に二重引用符を使用することです。

$ eval "cat < '$filename'"
hi

変数はシェルによって拡張されますが、変数内の引用符はファイル名を一緒に保持するため、まだ機能します。 (ファイル名にアポストロフィが含まれていると壊れることがあります。)

「動作しないもの」は次のとおりです。

$ eval "cat" "<" "$filename"

これはあなたの例と似ていますが、引用符を使用すると<外部シェルはリダイレクトを実行しません。evalその後、パラメーターを一緒に入れると、結果コマンドは次のようになります。

cat < my file

my fileこれで、引用符が消えたため、期待どおりに機能しません。

おすすめ記事