パラメーターにワイルドカードおよび/またはスペースが含まれている場合(該当するパラメーターがオプションの場合)、パラメーターを渡すのに問題があります。これは非常に抽象的に聞こえるので、簡単な例を見てみましょう。次のシェルスクリプトにはsome_command.sh
2つまたは3つのパラメータが必要です。最初の引数はコマンドラインスイッチでなければならず、2番目の引数はオプションであり、存在する場合は形式のコマンドラインスイッチでなければならず、最後の引数は必須であり、何でも構いません--NAME=VALUE
。
#!/bin/bash
# This is file some_command.sh
# Synopsis:
# some_command.sh --switch1=val1 [--switch2=val2] arg
echo "switch1: $1"
shift
if [[ "$1" == --*=* ]]
then
echo "switch2 ($1) detected"
shift
fi
echo argument is ${1:?argument missing}
some_command.sh
次のような他のスクリプトを介して呼び出すとしますcaller.sh
。
#!/bin/bash
# This is file caller.sh
if [[ ${1:-x} == x ]]
then
switch="--abc=long argument"
else
switch=""
fi
some_command.sh "--exclude=*~" "$switch" arg
引用を参照してください。引用符は、--exclude
シェル内のワイルドカード式を拡張できないため、必要であり、スペースを含む"$switch"
テキスト$switch
を含めることができ、引数をスペースに分割できないために必要です。
意図は、私たちが実行すると、caller.sh x
次のような結果が生じるはずです。
some_command.sh "--exclude=*~" "--abc=long argument" arg
たとえば、私たちが実行した場合は、caller.sh y
次のようになります。
some_command.sh "--exclude=*~" arg
私がcaller.sh
ここで提供するものは実際にいいえ後者の場合は実行されるのでうまくいきます。
some_command.sh "--exclude*~" "" arg
これは正確ではありません。
コマンドの前にプレフィックスを付けてみましたeval
。これは問題を解決しますが、$switch
二重引用符も削除され、"--exclude"
ワイルドカードはシェルで評価されます。
eval
引き続き追加の引用レベル(例:)が利用可能になりそうですが、"\"--exclude*~\""
これは悪い解決策です。誰もがこれを行うよりクリーンな方法があるかどうか疑問に思います。
私がなぜこの質問をするのか疑問に思った場合:zip
ファイル名のスペースを処理する必要があるスクリプトを書いている間、私は偶然この質問を見つけました。
しかし、上記のように、およびbash
で問題が発生しますzsh
。私はまた、シェルの1つだけが機能する賢い解決策にも興味があります。
答え1
配列は可変数の引数に拡張されるので、使用してください。
#! /bin/bash -
# This is file caller.bash
switch=()
if [[ ${1-x} == x ]]
then
switch=("--abc=long argument")
fi
some_command.sh "--exclude=*~" "${switch[@]}" arg
または、次の構文を使用できます${var+...}
。
#! /bin/sh -
# This is file caller.sh
unset switch
if [ "${1-x}" = x ]
then
switch="--abc=long argument"
fi
some_command.sh "--exclude=*~" ${switch+"$switch"} arg
zshを使用すると、次のことができます。
#! /bin/zsh -
switch=
if [ "${1-x}" = x ]
then
switch="--abc=long argument"
fi
some_command.sh "--exclude=*~" $switch arg
zsh
しないでください分割+グローバルパラメータ拡張ではそうではありません。空の除去これがあなたが望むものです。