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)

答え2

このタイプの分割はIFSとは関係ありません。

1行を単語に変換する最も基本的な分割です。

単語は、シェルが操作を実行できる単一のトークンです。文章を読むのと同じように、まず単語に分けて単語の意味を理解してください。

このような分裂を避ける唯一の方法は、引用することです。これが引用文が発明された根本的な理由である。

$ op.sh () { printf '%s\n' "$@"; }

$ op.sh one two three
one
two
three

$ op.sh "one two three"
one two three

もう魔法はありません。

関連情報