2017-03-29 1 views
1

せずに、パラメータ展開に特殊文字を使用しますシェルまたはシェルのいずれかの選択に影響する方法 設定、私の目標は、デフォルトの文字列値を使用することです(y!) という名前の変数は、xという名前の変数が設定されていないか、またはnullです。つまり、シェルに のパラメータ拡張を実行させたいのですが、yは、特殊文字を含まない テキストの略です。だから、単純は、移植性または二重引用符、次のシェルのすべてにおいて

${x:-(y!)} 

は、二重引用符があるかもしれません。多くの相違が明らかになり、シェルの中では がこれまたは変形を解釈します。試みの中で 移植性にアプローチすると、私は0から3を追加してみました\ s。私もまた はスペースの効果を試しましたが、私は今それを除外します。シェルによって示される差異の

${x:-(y!)}, ... , ${x:-\(y\!\)} 

一つは、私が推測する、歴史イベントの!のシェルの オーバーロードに関連することになります。 (zshで!echoを試してください) 二重引用符で囲まれたバリアントがある場合、他の違いが残ります。 私は実際に というスキームがこのコンテキストで使用されないことを期待できないので、ソリューションは二重引用符の間で理想的に動作します。 \が先行(!)との全てを有する即ちCOMAND echo "$0: ${x:-\(y\!\)}"、所与例えば

は、シェルは応答:

-bash: \(y\!\) 
ksh: \(y\!\) 
zsh: \(y!\) 
dash: \(y\!\) 

したがって、Zシェルは異なるように頼みます。それはzshの、kshの、次はbashで同様に動作して らしいことが判明し、ダッシュ:(?( は内蔵の場合でもecho、))

$ echo "${x:-$(echo \(y\!\))}" 
(y!) 

しかし、別のコマンド置換を伴う行き過ぎと思われます。より良い方法がありますか?全く?私は 何かを見つけましたか?

(Zshのは、それは違った応答理由かも説明している。(zshexpn(1))「隣接文字(必要な場合)からの歴史 参照を絶縁」するために、!{...}、そうではない\を使用しているようですか?! charの進コードを使用して)

+0

@Stephane Chazelas私はあなたがこの質問に答えるために適任者だと思う - 私たちはどのようにY 'について –

+2

を学ぶための機会となります= '(y!)'; echo "$ {x: - " $ y "}" '? POSIX準拠のシェルは、 'x'が設定されていないかヌルの場合は'(y!) 'に展開します。 –

+0

@ベンジャミンW。考えはかなりo.Kです。私自身のスクリプトのために(拡張する何もないときはいつでも、 '' '提案が十分であるように)。 'y'の名前を選ぶときには改善の余地があるかもしれません。しかし、拡張と二重引用符を使用する一般的に適用可能な手順として提供できるかどうかはわかりませんが、 "実用的"および "技術的理由"を含むいくつかの発言を追加して説得することができます。 – B98

答えて

1

が動作しているようです:様々なシェルの組み込みechoコマンドが矛盾している

/bin/echo -e "'${x:-(y\0041)}'" 

、(2)は-eスイッチが必要ですが、それをdash理解していません、/bin/echoはより信頼性が高いです。 4つのシェルをテストします。

unset x 
for f in dash bash zsh ksh ; do 
    echo -en "$f:\t" 
    $f -c "/bin/echo -e \"'\${x:-(y\0041)}'\"" 
done 

出力:

dash: '(y!)' 
bash: '(y!)' 
zsh: '(y!)' 
ksh: '(y!)' 
+0

'echo'コマンドは実際には矛盾しています。たとえば、Macで 'bash:\t -e '(y \ 0041)''と表示されます。しかし、これは拡張を外側に動かす別のヒントです。 – B98

関連する問題