私は小さなスクリプトを書いていますが、パイプ入力またはコマンドライン引数を介して実行したいと思います。
my_function() {
for i in "$@"; do
echo "$i"
echo -----
done
}
if [ -t 0 ]; then
my_function "$@" # command-line arguments
else
my_function $(cat) # pipe
fi
次のオプションが有効です。
$ my_script 1 2 3 4
$ echo 1 2 3 4 | my_script
1
-----
2
-----
3
-----
4
-----
これもうまくいきます:
$ my_script 1 "2 3" 4
1
-----
2 3
-----
4
-----
パイプラインで位置パラメータを保存しようとすると問題が発生します。
$ echo 1 "2 3" 4 | my_script
1
-----
2
-----
3
-----
4
-----
$ echo 1 "'2 3'" 4 | my_script
1
-----
'2
-----
3'
-----
4
-----
代わりに良い結果なしでmy_function $(cat)
試してみました。たとえば、次のようになります。read
read input
my_function $input
これについて考えていますか?私は単語の分割が難しいことを知っています。
答え1
bash 4.4を使ってこのテクニックを見てみましょう。
function myf {
if ! [ -t 0 ];then
declare -a args=\($(</dev/stdin)\);
set -- "${args[@]}";
fi;
for i in "$@";do
echo "$i";
echo -----;
done
}
テスト:
$ function myf { if ! [ -t 0 ];then declare -a args=\($(</dev/stdin)\);set -- "${args[@]}"; fi;for i in "$@";do echo "$i";echo -----;done }
$ myf 1 "2 3" 4
1
-----
2 3
-----
4
-----
$ echo $'1 "2 3" 4'|myf
1
-----
2 3
-----
4
-----
以下を使用して同じ結果を得ることができます。
$ echo 1 \"2 3\" 4 |myf
$ echo 1 "'2 3'" 4 |myf
ただし、echo 1 "2 3" 4
bashはこの構文の二重引用符を無視するため、機能しません。
$ echo 1 "2 3" 4
1 2 3 4