次のコードは私が試したZsh 5.8で動作します。セミコロンが抜けたにもかかわらず。しかし、これは本当に有効なZsh構文ですか?
#!/bin/zsh
if var='value' then
echo 'then'
fi
割り当て結果なしparse error near `fi'
:
#!/bin/zsh
if true then
echo 'then'
fi
セミコロンを使用した正しい構文:
#!/bin/zsh
if true; then
echo 'then'
fi
セミコロンのないコードは、sh、Bash、およびKsh 93では正しくありません。
if ... then
Zshは、特定の状況で同じ行にセミコロンなしでのみ許可するという事実が混乱しています。条件付き役職の割り当ては特別な場合のようです。ドキュメントにはいつセミコロンが必要なのか正確には記載されていません。
https://zsh.sourceforge.io/Doc/Release/Shell-Grammar.html#index-if-construct
実際に私の興味はKshです。。実際にKsh 93を達成しようとすると、次のエラーが発生しますsyntax error at line ...: `fi' unexpected
。しかし、Zshで実行するとemulate ksh
うまくいきます。私はこれが実際にKshではなくZshであり、実際のKshでは常に間違いであるため、うまくいくと思います。これを確認する正確な文書はありますか?
sh、Ksh、Bash、Zshでの試みとその出力は次のとおりです。 https://bitbucket.org/OPiMedia/hel言語s/src/master/comparative/shell/if_then/
ベストアンサー1
割り当てられたら、コマンドを実行できます。たとえば、
LC_ALL=C grep foo file
rc
Bourneに似たシェルまたは-likeシェルfish
で有効です。そして、inとinを使っ/path/to/grep
て実行することを意味します(シェルはシステムが呼び出すすべてのインタフェースの前に配置されます)。grep
foo
file
argv[]
LC_ALL=C
envp[]
execve(file, argv[], envp[])
then
したがって、パーサーがこのトークンを/構成のキーワードとして受け入れて認識することはまったく驚くべきことではありません。then
これは、コマンドが必要なすべての場所で必要なためです。if
fi
then
また、次のことができることがわかります。
if then else (echo foo) fi
同じ理由で。
ただし、文書化されておらず、将来変更される可能性があるため、これに依存しません。
if true then
or にはif echo then
明らかに / の引数がありますが、then
構造体にはその引数はありません。true
echo
if
then
実際には、POSIXではthen
(構文的に)キーワードとして認識されることはできません。var='value'
sh
POSIXの要件:
var=value keyword
keyword
キーワードとして認識されるわけではありませんが、実行されるコマンドの名前であまり役に立ちません。しかし、POSIXシェルキーワードの後にコマンド名を指定する人は誰もいません。
たとえば、POSIXには次のものが必要です。
var=value if true
if
true
引数として渡され、var=value
その環境で実行できる場合は、コマンドが実行されます。
$ ln -s /bin/printenv bin/if
$ a=bar bash -c 'if a'
bash: -c: line 1: syntax error: unexpected end of file
$ bash -c 'a=foo if a'
foo
$ zsh -c 'a=foo if a'
zsh:1: parse error near `if'
zshがこの要件に従わない場合(シミュレーションでもsh
)、実際に問題が発生する可能性はほとんどありません。私は、誰かがというコマンドを呼び出すことを望むまれな場合には、前にリダイレクトがあるかどうかにかかわらず、コマンドを書いたりキーワードif
で誤認したりしない'if'
ようにしたいと"if"
思います。\if
if
var=value
$ a=bar bash -c '"if" a'
bar
$ bash -c 'a=foo "if" a'
foo
$ a=bar zsh -c '"if" a'
bar
$ zsh -c 'a=foo "if" a'
foo
ちなみに、POSIXには以下が必要です。
if true; then if true; then echo x; fi fi
(2つの間に改行やセミコロンがないfi
)は奇妙な要件ですが、ksh88が実行するアクション(Bourneシェルから継承されます)を指定するだけです。これはPOSIX仕様が主に基づく実装です。
zsh
この要件は尊重されず、最後に追加の単語を追加することはできませんfi
。
if (true) then (echo x) fi
を含むほとんどのシェルで動作しますzsh
が、IIRC POSIXはこの場合その動作を指定しません。
1 実際に歴史的な逸話として初期Unicesにif
。これは Bourne シェルまたは C シェルの前にあり、後で独自のif
構成をとりました。その後、これらの構造が重複しているため、削除してください。