2017-03-10 3 views
0

以下に示すように、コマンド置換は引用されたコマンドライン引数の解釈を変更します。フードの下で何が起こっていますか?回避策がありますか?コマンド置換は引用符で囲まれた引数を空白で区切ります

$ cat dumpargs.sh 
#! /usr/bin/env bash 
for i in "[email protected]" 
    { 
    echo "$i" 
    } 

$ cat testfile.txt 
'1 space' '2 space' 

$ ./dumpargs.sh $(cat testfile.txt) ## produced undesired output 
'1 
space' 
'2 
space' 

$ ./dumpargs.sh '1 space' '2 space' ## produces desired output 
1 space 
2 space 
+0

http://shellcheck.net/はあなたの問題(文字列分割につながる引用符の欠如)を捕まえていました。リテラル*引用符(文字列分割に影響しない)が*構文的なものとして扱われるという期待はおそらくより大きな問題です。 –

+0

これは[BashFAQ#50](http://mywiki.wooledge.org/BashFAQ/050)とも非常に関連しています。 –

+1

'xargs':' cat testfile.txt | xargs。/ dumpargs.sh' – nobar

答えて

2

あなたはコマンドラインで./dumpargs.sh '1 space' '2 space'を書くとき、シェルスクリプトに引数を渡す前に、単一引用符を解釈します。引数1の値は1 space、引数2の値の値は2 spaceです。一重引用符は値の一部ではありません。

./dumpargs.sh $(cat testfile.txt)と書くと、 と書いても、シェルはtestfile.txtの内容を解釈しようとしません。 シェルは、コマンドラインで入力された実際のテキストのみを解釈します。 この例のような置換されたコンテンツ、または変数の値は解釈されませんが、文字通り使用されます。 最後に、シェルは、区切り文字をIFSで使用して、コマンド行の文字列に単語分割を実行します。 したがって、一重引用符は文字通り使用され、 であり、内容は単に空白で分割されます。

while read -r line; do 
    echo "$line" 
done 

あなたは./dumpargs.sh < testfile.txtでそれを呼び出すことができます。

一つの可能​​な回避策は、単一引用符なしで、1行に1つの引数を格納し、dumpargs.shは標準出力からの引数を取るようにすることです。

+0

あなたの回避策は私が探していたものではありませんが、さまざまな使い方で状況がどのように解釈されるかの違いについてのコメントに感謝します。 Bashの文字列処理に関連するすべてのものが私の頭を傷つけます。 – nobar

関連する問題