Bashパラメータ分割を無効にする方法は?

Bashパラメータ分割を無効にする方法は?

私はスクリプトに行入力を取得し、スペースや他のものに分割せずに二重スペースを削除せずに単一のパラメータのように「現状のまま」処理したいと思います。例:

# op.sh
IFS=$'\n'
echo "$*"

./op.sh one two   three
one
two
three

# Desired output
./op.sh one two   three
one two   three

したがって、改行(入力)まで読み込まれます。

ベストアンサー1

プログラム(スクリプト、アプリケーションなど)は自分自身を呼び出すコマンドラインを見ることができません。呼び出しシェルで解析される一連のゼロ個以上の引数を取得します。

たとえば、実行時にls f*処理されるのはシェルではありません。 fで始まる3つのファイルがある場合、シェルは次のように解析してそれを実行できます。この場合、代わりに次の3つの引数を参照してください。lsf*ls f*ls final food fredlsf*

./op.sh one two three同様に、シェルを実行すると、./op.shスペースで区切られた3つの引数、oneおよびtwoとして解析されますthree。スペースは解析の一部として削除されます。次のスクリプトでこれを見ることができます。

#!/bin/bash
for a in $*; do echo "Found * argument ($a)"; done
echo
for a in "$@"; do echo "Found @ argument ($a)"; done
echo
echo "All together, they are ($*)"

呼び出されるとargs実行可能にし(chmod a+x args)、次のように呼び出すことができます。

./args one two   three

対応する出力は次のとおりです。

Found * argument (one)
Found * argument (two)
Found * argument (three)

Found @ argument (one)
Found @ argument (two)
Found @ argument (three)

All together, they are (one two three)

これを試してみると、$*コマンドライン引数の場合、各引数がスペースで区切られ、内部スペースが再び区切られていることがわかります。これは通常は動作しません。代わりに二重引用符を使用すると、"$@"誤ってパラメータを解析するのを防ぐことができます。ただし、どちらの場合も、引数は元のコマンドラインのコピーではなく、構文解析された引数で再構成されます。

スペースを残すには文字列を引用する必要があります。二重引用符を使用すると、$(...)変数と構造を拡張できます。一重引用符はリテラルを残します。ここでは一重引用符を使用します。

スペース引用

./args 'one two   three'
Found * argument (one)
Found * argument (two)
Found * argument (three)

Found @ argument (one two   three)

All together, they are (one two   three)

アポストロフィ

'one more $HOME to go'
Found * argument (one)
Found * argument (more)
Found * argument ($HOME)
Found * argument (to)
Found * argument (go)

Found @ argument (one more $HOME to go)

All together, they are (one more $HOME to go)

二重引用符

./args "one more $HOME to go"
Found * argument (one)
Found * argument (more)
Found * argument (/home/roaima)
Found * argument (to)
Found * argument (go)

Found @ argument (one more /home/roaima to go)

All together, they are (one more /home/roaima to go)

おすすめ記事