web-dev-qa-db-ja.com

シェル全体のバックスラッシュの処理

echoおよびprintfは、zshbashおよびその他のシェルのバックスラッシュをどのように処理しますか?

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だけを印刷するにはどうすればよいですか?

更新(注:これは現在、Stephaneのコメントで回答されています)

私はzsh 5.0.2で以下を試しました:

function foo
{
    printf '$s\n' $1 
}

foo '\\some\path'

しかし、これは$sを出力しますか?

zshechoは、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これは、失われたバックスラッシュを再発明することはできません。

12

新しい答え: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に同じことを伝えるために、そこに「\」をエスケープする必要がある方法を参照してください:「それはリテラル "\"が欲しい」)(そして、シェルが解釈するのを避けるために、「」ではなく「」で囲むことに注意してくださいそのほとんども)

1
Olivier Dulac

バックスラッシュisはエスケープ文字であるため、一般的にはできません(したがって、リテラル値が必要な場合はエスケープする必要があります)。 BASHはこの目的のために単一引用符を提供しますが、単一引用符で囲まれた文字列内で単一引用符をエスケープすることはできません。

echoの不一致に関しては、これは組み込みであり、シェル間で(ある程度)異なる動作をする場合があります。たとえば、BASHビルトインには-eオプション。バックスラッシュシーケンスを解釈するように指示します。これを使用すると、Zシェルで見た動作を取得できます。

1
peterph