echo
およびprintf
は、zsh
、bash
およびその他のシェルのバックスラッシュをどのように処理しますか?
zshの場合、次の動作が発生します。
$ echo "foo\bar\baz"
foaaz
$ echo "foo\\bar\\baz"
foaaz
$ echo 'foo\bar\baz'
foaaz
$ echo 'foo\\bar\\baz'
foo\bar\baz
bashでは、状況は少し一貫しているように見えます。
bash$ echo "foo\bar\baz"
foo\bar\baz
bash$ echo 'foo\bar\baz'
foo\bar\baz
bash$
しかし、より具体的に:\\foo\bar\something
)などのバックスラッシュを含む文字列をどのように渡すことができますか:
echo
printf
print
およびまったく同じ文字列を取得しますか?(zsh
およびbash
内)?
次に、zshの関数を使用した別の実験を示します。
function foo
{
echo -E '$1'
}
$ foo \\here\is\some\path
$1
\\here\is\some\path
だけを印刷するにはどうすればよいですか?
私はzsh 5.0.2で以下を試しました:
function foo
{
printf '$s\n' $1
}
foo '\\some\path'
しかし、これは$s
を出力しますか?
zsh
echo
は、UNIXモードのbash
のように、標準的な方法で動作します。つまり\b
をASCII BS文字に変換するUNIX仕様で必要です。
echo
を使用して任意の文字列を表示しないでください。printf
を使用してください:
printf '%s\n' "$1"
print -r -- "$1"
も機能しますが、ksh
/zsh
固有です。
echo -E - "$1"
はzsh
で動作し、いくつかのBSDを信じています。
cat << EOF
$1
EOF
printf
コマンドがなかった数十年前のものでさえ、あらゆるBourneのようなシェルで動作しますが、新しいプロセスを生成します。そして、今ではprintf
がどこにでもあるので、今日は本当に必要ありません。
ちなみに、バックスラッシュはシェルにとって特別なものであるため(シェルはすべてrc
)、バックスラッシュをエスケープする必要があります。
$ foo '\\foo\bar'
foo \\foo\bar
は"\foo\bar"
string to foo
これは、失われたバックスラッシュを再発明することはできません。
新しい答え:read -r var
-r raw input - disables interpretion of backslash escapes and line-continuation in the read data
表示するには:
printf "%s" "$var"
echo "$var"
うまくいくはずです。
したがって、foo関数の場合:
function foo
{
read -r var
echo -E "var is : ${var}"
}
$ foo
\\here\is\some\path
var is : \\here\is\some\path
以下の古い答え(答えないが、多分役に立つ^^)
各\
を\\
で置き換えるだけで、シェルに「それがリテラル\
欲しい」と伝えます。それ以外の場合(例では、zshの場合)、\b
は「1バックスペース」などを意味する可能性があります。
たとえば、sedを使用できます。
sed -e 's,\\,\\\\,g' < the_original > the_escaped_backslaches_version
(sedに同じことを伝えるために、そこに「\」をエスケープする必要がある方法を参照してください:「それはリテラル "\"が欲しい」)(そして、シェルが解釈するのを避けるために、「」ではなく「」で囲むことに注意してくださいそのほとんども)
バックスラッシュisはエスケープ文字であるため、一般的にはできません(したがって、リテラル値が必要な場合はエスケープする必要があります)。 BASHはこの目的のために単一引用符を提供しますが、単一引用符で囲まれた文字列内で単一引用符をエスケープすることはできません。
echo
の不一致に関しては、これは組み込みであり、シェル間で(ある程度)異なる動作をする場合があります。たとえば、BASHビルトインには-e
オプション。バックスラッシュシーケンスを解釈するように指示します。これを使用すると、Zシェルで見た動作を取得できます。