- 書式
- eval [COMMANDS...]
概要
eval
は指定された引数を
コマンドとして評価します。
1つ以上の引数が指定されたとき、
すべての引数は
スペースを使って連結されます。
実行例
以下の例では
ls
コマンドを呼びます。
他のシェルと違って 、
fishにおいては、
コマンドそのものを
シェル変数として使えません。
それを回避するために
eval
を使います。
set cmd ls eval $cmd
訳注:上記の方法は落とし穴があります。
やはりfishにおいては
関数 を定義するべきです。
スペースを含むファイル名に注意
上記の方法には重大な欠点があります。
eval
でスペースを含む
ファイル名を扱うときには、
二重でクオート・エスケープする
必要があります。
/tmp/xx
ディレクトリにて
実証してみます。
スペースを含まない
ファイル名についてはOKです。
$ cd /tmp $ mkdir xx $ cd xx $ touch a.txt $ set cmd ls $ eval $cmd a.txt
ところが、
スペースを含むファイル名では
破綻します。
なぜなら eval
は、
すべての引数をスペースで連結
するからです。
eval $cmd 'file with spaces.txt'
は、
ls file whith spaces.txt
として評価されるため
うまくいきません。
$ touch 'file with spaces.txt' $ eval $cmd 'file with spaces.txt' ls: 'file' にアクセスできません: そのようなファイルやディレクトリはありません ls: 'with' にアクセスできません: そのようなファイルやディレクトリはありません ls: 'spaces.txt' にアクセスできません: そのようなファイルやディレクトリはありません
そのためには、
- クオート内でクオートを入れるか
- クオート内でエスケープする
必要があります。
$ ls 'file with spaces.txt' file with spaces.txt $ eval $cmd "'file with spaces.txt'" file with spaces.txt $ eval $cmd '"file with spaces.txt"' file with spaces.txt $ eval $cmd 'file\ with\ spaces.txt' file with spaces.txt $ eval $cmd "file\ with\ spaces.txt" file with spaces.txt
結局は function で
関数定義するのがベストです。
$ function cmd; ls $argv; end $ cmd 'file with spaces.txt' file with spaces.txt
後片付け。
$ cd $ rm -rf /tmp/xx
最後までお読みいただき、ありがとうございました。参考になれば嬉しいです。