引用されたシェル算術拡張

引用されたシェル算術拡張

BashとDashでは、算術拡張に引用符を使用するのは違法です。

$ bash -c 'x=123;echo $(("$x"))'
bash: "123": syntax error: operand expected (error token is ""123"")
$ dash -c 'x=123;echo $(("$x"))'
dash: 1: arithmetic expression: expecting primary: ""123""

Bashはshで呼び出されたときに同じエラーを発生させます。しかし、KshとFreeBSDのBourne Shellは、次のことを気にしません。

$ ksh -c 'x=123;echo $(("$x"))'
123
$ sh -c 'x=123;echo $(("$x"))'
123

~によるとバッシュリファレンスマニュアル:

式は二重引用符で囲まれたように処理されますが、括弧内の二重引用符は特に処理されません。すべてのトークンは...引用符の削除を経験します。

(本質的にはPOSIX説明する。 )

最後に、Bashはこれを他の算術コンテキスト(たとえば条件式)とは異なる方法で$(( ))処理します。(( ))後者は引用符を使用しても大丈夫です。

それとも何か理解していません。見積もりの​​削除ここを意味します。それ以外の場合は、これらのシェル実装の一部のバグです。前者の場合、「引用符の削除」とは正確に何を意味しますか?それともこれはただのバグですか?

ベストアンサー1

これが間違った実装なのか、それとも間違ったドキュメントなのか混乱しています。 Bashは、参照の削除について次のように言います。

見積もりの​​削除

前の拡張の後、上記のいずれかの拡張で発生しなかった引用符のないすべての文字、 \および '"削除されます。

私の考えの中核は「みんな」だと思います。引用しない段落のすべての内容は$(( ))二重引用符で囲まれているかのように処理されます。これらの文字が括弧内にある場合は、すべて引用され、デフォルトでは引用符の削除は不要です。たとえば、他の「削除」文字の処理方法に注意してください(引用符付き文字列の解析方法によって末尾のスペースがどのように保持されるかを参照してください)。

$ echo $(( '5' ))
bash: '5' : syntax error: operand expected (error token is "'5' ")
$ echo $(( \ ))
bash: \ : syntax error: operand expected (error token is "\ ")

ソースコードを調べると、コードが数学かネストされたレガシーサブ式であるかどうかを確認するために、コードを検索するときに引用符のバランスを取る必要があります$(( ))。文字列が算術式として認識されると、二重引用符で解析されます。みんな内部文字は、引用符が削除されるまで引用符で囲まれたと見なされます。

個人的にこれが私がkshを好む理由の1つです。特に数学の場合はさらにそうです。たとえば、上記の一重引用符5を53と評価されたC文字列として扱います。 man asciiこれがなぜ意味があるのか​​調べてください。 :)

おすすめ記事