私はbashの専門家ではありませんが、最近bashスクリプトを書いていますが、毎回パラメータを引用するのは本当に面倒です。このシェルの動作を変更する方法はありますか?文字列が引用されていない場合でも分割されないようにしたいと思います。
PS - IFSをnullに設定すると、すべてのパラメータが削除されるため、効果はありません。私が望むのは、執筆時です。
func1() {
echo $1 $2 $3
}
func2() {
echo "number of arguments func2 got: $#"
}
func2 $(func1 firstarg "second arg is a multi word string" "third arg is also a multi word string")
以下を印刷します。
number of arguments func2 got: 3
編集、指摘したコメントのおかげで:私の例ではechoを使用しているので、コードはfunc2の引数を参照するかどうかに応じて1つまたは14の引数を取得するように印刷します。ところで、私が言及した予想結果のように、関数から複数の値を破壊せずに返す方法を探しています。
ありがとうございます!
答え1
タイトルの質問に答えるために単語の区切りを無効にする方法は、空のIFS
文字列に設定することです。
しかし、テキストで説明されている内容は、コマンド置換を介して渡した後に複数のマルチワード文字列を区別して保持することがより困難です。実際にこれを行う簡単な方法はありません。
ここでの基本的な問題は、コマンド置換の結果(〜呼び出された関数の標準出力出力)が単に文字列(バイトストリーム)であり、ここに複数の文字列を合わせようとすることです。通常、これらの文字列にはランダムな内容が含まれており、これは非常に基本的な問題です。
あまり変わりません。コマンドを変数に保存、ここではコマンド置換を行っているだけです。
回避策は、区切り文字として使用するいくつかの文字を予約し、IFS
その文字に設定することです。デフォルトでは、空白IFS
、タブ、および改行文字を区切り文字として使用しますが、これは明らかに空白のある文字列では機能しません。空の文字列に設定すると、対応するIFS
区切り文字がないため、常に1つのフィールドしか取得されません。
ただし、たとえば、改行でのみ設定できますIFS
(文字列が複数行ではないと仮定)。
#!/bin/bash
IFS=$'\n'
foo() {
printf "%s\n" "$@"
}
nargs() {
echo "number of arguments nargs got: $#"
}
nargs $(foo firstarg "multi word string" "also a multi word string")
(ただし、コマンド置換は、関係なく末尾の改行文字を削除するため、リストの末尾に空の文字列を使用することはできません。IFS
)
別のアプローチは、関数の標準出力を使用するのではなく、変数名を関数に渡し、関数をnamerefを介して名前付き配列に書き込むことです。
#!/bin/bash
bar() {
declare -n _out="$1"
shift
_out=("$@")
}
nargs() {
echo "number of arguments nargs got: $#"
}
bar tmparr firstarg "multi word string" "also a multi word string"
nargs "${tmparr[@]}"
_out
(呼び出された変数が関数の外部にも存在する場合、変数の範囲の指定に問題があります。)
また、引用符のない拡張(変数またはコマンドの置き換え)がある場合、結果はファイル名のワイルドカードの影響を受けるため、無効な12 * 34
ワイルドカードも使用しない限り、このような出力は重大に歪みますset -f
。
答え2
もともと欲しかったのはパラメータ拡張後の単語分割を無効にする、だから書かないで
mcd() {
mkdir -p "$1"
cd "$1"
}
書くことができます
mcd() {
mkdir -p $1
cd $1
}
それは何が起こっても動作しますmcd "foo bar"
。
これはほとんどのユースケースで推奨される動作であるため、デフォルトの動作にzsh
設定されます(SH_SPLIT_WORD
オプションを使用してグローバルに無効にするか、作成して個別に無効にすることができます${=1}
)。
解決策を求めたことはわかりますがbash
、zsh
代わりに使用bash
「これは私の問題の多くに対する答えであり、zsh
ある日、文字通りこの方法に切り替えてから抜け出すことになりました。だからこのアドバイスを他の人に伝えることができて嬉しいです。IMHO、これに固執する理由はほとんどありませんbash
。