/usr/bin/time
組み込みシェル(bashとzsh)の違いを議論しながら、time
誰かが\time
getを省略形で使用できると述べました/usr/bin/time
。
当初、これは簡単で良い近道のように見えましたが、いくつかの問題が発生しました。
- なぜ
t\ime
動作しますか? \cd
ディレクトリを変更しないのに、なぜディレクトリを変更するのですか/usr/bin/cd
?
明らかに\foo
同じではありません$(which foo)
。今質問は次のとおりです。
bashとzshで観察される動作は\foo
シェルのPOSIX定義に含まれていますか?それでは、なぜこのように動作しますか?
脚注1:/usr/bin/cd
私のシステムでは
#!/bin/sh
builtin cd "$@"
答え1
t\ime
または\cd
(または、または、または"tim"e
最終的にまたは解決されると考えることができる他のすべての引用と拡張の組み合わせ)は、合計を作成する別の方法です。'cd'
${-##*}time
${-+time}
time
cd
cd
time
cd
しかし、これは最終的にシェルの解析と解釈の間またはtime
それ以降に解決されます。特に、これはシェルキーワードが認識されてから長い間発生します。ニックネーム交換が発生します。
したがって、シェルがその言語のキーワードを見つけると、シェルキーワードti\me
として認識されません。time
だから:
ti\me echo test
time
シェルは、キーワードの後に単純なコマンドが続くのではなく、単純なコマンドとして認識されます。
その後、引用が処理されますti\me
(ここでバックスラッシュはm
とにかく引用する必要がない文字を引用し、引用文字は削除されて取得されますtime
)。time
注文する他のコマンドのように検索されます(の組み込みコマンド、関数、および実行可能ファイルのリストから。$PATH
おそらく/bin/time
ここにあります)。
シェル言語にはキーワードがなく、cd
組み込みコマンド(あなたのコマンドよりも優先されます)のみがあります。ただし、(たとえば)のエイリアスを定義する場合も同様です。エイリアスの置換は非常に早く行われます。引用符が削除される前にエイリアスなしでエイリアスがある場合(バックスラッシュを含むエイリアスを許可するシェルはあまりありません)、次のように作成します。cd
cd
/usr/bin/cd
cd
alias cd=pushd
cd
\cd
\cd dir
cd
エイリアスが置き換えられていないことを確認しようとしています。
簡単に言えば、コマンド名またはその一部を引用すると、そのコマンドがシェルキーワードとして処理されるのを防ぎます(while
、、、、...などのキーワードはfor
、if
{
time
一部シェルのみ) 使用可能なエイリアスを無視します。
$PATH
ただし、コマンドが実行可能ファイルとして検証されることを強制するわけではありません。機能(こうすれば解決できますcommand time cmd...
)組み込み(組み込みコマンドを持つシェルenv time cmd...
はわかりませんが、これを行うことでこの問題を解決できます。)time
引用は、一部のシェルでは/// typeset
...一連の特殊な組み込み関数の動作にも影響します。バラよりdeclare
export
local
ローカル変数の割り当てには引用符が必要ですか?もっと学ぶ。