
みなさん、こんにちは。よろしくお願いします。
フォーラムで自分の状況を検索しましたが、解決策を見つけることができませんでした。コマンド ラインで引数/オプション/パラメータを渡すスクリプトがあります。値の 1 つにスペースが含まれているため、二重引用符で囲みました。例を挙げたほうが簡単かもしれません。引数/オプション/パラメータの使い方についてはご容赦ください。
$: ./test1.ksh -n -b -d "Home Videos"
私の問題は、変数を「ホーム ビデオ」に設定し、それを一緒に使用することです。私の例では、-d はディレクトリを指定するためのものです。すべてのディレクトリにスペースがあるわけではありませんが、私の場合はいくつかのディレクトリにスペースがあります。
これは、期待どおりに動作しないコードの例です。
#!/bin/ksh
Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}
SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
case $1 in
-[dD])
shift
export DirectoryName=$1
;;
-[nN])
export Var1=No
shift
;;
-[bB])
export Var2=Backup
shift
;;
*)
shift
;;
esac
done
Function2
}
Function2()
{
echo "Directory Name: ${DirectoryName}"
}
Function1 $*
これを実行すると、DirectoryName に Home Videos ではなく Home のみが取得されます。以下を参照してください。
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 5
Function1 Args: -n -b -d Home Videos
Number of Args in SetArgs: 5
SetArgs Args: -n -b -d Home Videos
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home
私が期待していたが実現できなかったことは次のとおりです。
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 4
Function1 Args: -n -b -d "Home Videos"
Number of Args in SetArgs: 4
SetArgs Args: -n -b -d "Home Videos"
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home Videos <-- Without double quotes in the final usage.
これに関して何か助けていただければ大変ありがたいです... 二重引用符をエスケープしようとしましたが、成功しませんでした。
これを解決するのにご協力いただき、ありがとうございました。
よろしく、ダニエル
答え1
引用符の使用$*
または$@
引用符なし一度もない意味が通じます。
"$*"
は、位置パラメータとの最初の文字(またはシェルによってはバイト)の連結であり$IFS
、"$@"
位置パラメータのリストです。
引用符で囲まれていない場合も同様ですが、zsh
他の引用符で囲まれていないパラメータ展開と同様に、split+glob(または を使用した空の削除のみ)の対象となります(シェルによっては、 が空の$*
場合でも の引数を分離するものもあります$IFS
)。
ここで引数のリストを渡しますそのまま関数に追加すると次のようになります:
SetArgs "$@"
[...]
Function1 "$@"
ksh88 では、$IFS
正常に動作するためにはスペース文字 (デフォルトで含まれています) が含まれている必要があることに注意してください (Bourne シェルから継承されたバグで、ksh93 で修正されました)。
また、一部の実装(エミュレーションksh
の古いバージョンなど)では、zsh
ksh
export DirectoryName=$1
はsplit+glob呼び出しのケースです。Kornexport
のようなシェルでシェルコードを評価できるコマンドの1つです。配列インデックスの算術評価を通じて)、 っていうことはコマンドインジェクションの脆弱性を回避するために変数を引用符で囲むことが重要となるケースの1つ。
例:
$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux
[ $# -gt 0 ]
は意味をなさない別の split+glob 呼び出しであることに注意してください(少なくとも のデフォルト値では問題になる可能性は低くなります$IFS
)。
答え2
getopts
組み込みのシェルコマンドを使用して引数を解析することを検討しましたか(たとえば、@Stéphane Chazelasが提案したように)このコメント)? そうすれば、こうした面倒な作業が大幅に軽減されます。
あなたの場合、関連するコードは次のようになります。
while getopts "nbd:" argname
do
case "$argname" in
n) Var1="No" ;;
b) Var2="Backup" ;;
d) DirectoryName ="$OPTARG" ;;
?) echo -e "usage is..."
exit 1 ;;
esac
done