19

bashに改行記号を含む変数を出力するのと少し混乱しています。

var="Age:\n20\ncolor:\nred"
echo -e $var
Age:
20
color:
red

これは機能していますが、多くの人が、オプション付きのエコーは移植性がなく、 printfを使用する方が良いと言います。

私はprinfを使ったことがありません。エコーコマンドを放出するためのマニュアルによると:

printf '%s\n' "$var"
Age:\n20\ncoloe:\nred

ただし、これは変数内の\nを解析しません。マニュアルには通常、次の例があります。

printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME"

しかし、それは私の場合ではなく、私の観点からは、使用するのは快適ではありません。入力するだけで、これを使用できることがわかりました。

printf "$var\n"

ポータブルですか?次に$varをメールコマンドに渡すと、改行が保存されますか?

printf "$var\n" | mail -s subj email@domain.com 
4

1 に答える 1

38

printf%bフォーマット指定子は、特に置き換えることを意図しており (実際には、デフォルトで引数の特別な解釈を要求echo -eする XSI 拡張機能は指定されておらず、POSIX では許可されていません)、および へのフォーマット文字列引数。echo-e$'...'printf

 $ ( var='Age:\n20\ncolor:\nred'; printf '%b\n' "$var" )
Age:
20
color:
red

プログラムが正確な値を制御し、特にフォーマット文字列にすることを意図していない限り、通常は変数をフォーマット文字列に展開することは避けてください。特に最後の例は、printf-vオプションにより、Bash で非常に危険になる可能性があります。

# Bad!
var='-v_[$(echo "oops, arbitrary code execution" >&2)0]'
printf "$var" foo

%b特別な移植性要件がない限り、通常は避けることをお勧めします。リテラル データの代わりに変数にエスケープ コードを格納すると、コードとデータの分離の原則に違反します。これで問題ない状況もありますが、通常は引用符を使用して値を割り当てる方が適切です$'...'。これは、POSIX の次のバージョンで指定されており、Bash およびほとんどの ksh フレーバーで長い間利用できます。

x=$'foo\nbar'; printf '%s\n' "$x"    # Good
x=(foo bar); printf '%s\n' "${x[@]}" # Also good (depending on the goal)
x='foo\nbar'; printf '%b\n' "$x"     # Ok, especially for compatibility
x='foo\nbar'; printf -- "$x"         # Avoid if possible, without specific reason
于 2013-03-22T08:43:55.900 に答える