omxplayer
私のRaspberryPi(Raspbianの実行)には、複数のファイル名を引数として1つずつ再生(使用)するbashスクリプトがあります。基本構造は次のとおりです。
#!/bin/bash
for f in ${*}
do
echo "${f}";
done;
これで、入力ファイル名にスペースが含まれていると問題が発生します。特に動作が一貫していないようです。 2つのファイルがtest a b
あり、test d e
同じディレクトリにあるとします。他のパラメータを使用して上記のスクリプトを実行すると、次の結果が生成されます。
$ ./test test\ a\ b
test
a
b
$ ./test "test a b"
test
a
b
$ ./test test\ a*
test
a
b
$ ./test "test a*"
test
a*
しかし、奇妙なことは次のとおりです。
./test "test*"
test a b
test d e
明らかに、最後のバリエーションだけが予想される出力を提供します。ただし、特に単一のファイルを表示したい場合(タブの完成でフルネームが埋められている)、ファイルパスのフォルダ名の1つにスペースが含まれている場合は使用するのが面倒です。
常に期待どおりに実行されるようにシェルスクリプトで何ができるのですか?特に、両方
$./test test*
$./test test\ a\ b test\ d\ e
同じ出力を生成する必要があります。
test a b
test d e
したがって、一般的なタブ補完を使用してスクリプトを簡単に使用できます。
答え1
"$@"
代わりに使用してください${*}
(参照特殊パラメータマニュアルにあります)
for f in "$@"; do
echo make sure you quote your "$variables" everywhere in the loop
速記があります(そしてより移植可能です):
for f do ...
for f; do
一部のシェルでも動作しますが、標準ではありません。
答え2
while
別のアプローチは、次の2つの方法のいずれかでループを使用することです。
input_cmd|while read i; do
echo "$i";
done
または、次の手順で交換してください。
while read i; do
echo "$i";
done < <(input_cmd)
私が知る限り、後者はbashismなので、他のBourne互換シェルでは動作しないかもしれません。
ただし、コマンドラインから入力を受け取るので、for
以前の回答で提供されたループソリューションに固執するのが最善です。
man xargs
また、外部コマンドライン引数を処理するための最良の方法である場合もあるので、見てください。