Art*_*ero 5 pipe shell-script arguments
我正在编写一个小脚本,我想让它通过管道输入或命令行参数工作。
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
Run Code Online (Sandbox Code Playgroud)
这些选项有效:
$ my_script 1 2 3 4
$ echo 1 2 3 4 | my_script
1
-----
2
-----
3
-----
4
-----
Run Code Online (Sandbox Code Playgroud)
这也很好用:
$ my_script 1 "2 3" 4
1
-----
2 3
-----
4
-----
Run Code Online (Sandbox Code Playgroud)
当我试图从管道中保留位置参数时,问题就出现了:
$ echo 1 "2 3" 4 | my_script
1
-----
2
-----
3
-----
4
-----
Run Code Online (Sandbox Code Playgroud)
$ echo 1 "'2 3'" 4 | my_script
1
-----
'2
-----
3'
-----
4
-----
Run Code Online (Sandbox Code Playgroud)
而不是my_function $(cat)
,我尝试使用read
但效果不佳,例如:
read input
my_function $input
Run Code Online (Sandbox Code Playgroud)
对此有何想法?我知道分词很难。
使用 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
}
Run Code Online (Sandbox Code Playgroud)
测试:
$ 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
-----
Run Code Online (Sandbox Code Playgroud)
使用以下方法也可以获得相同的结果:
$ echo 1 \"2 3\" 4 |myf
$ echo 1 "'2 3'" 4 |myf
Run Code Online (Sandbox Code Playgroud)
但echo 1 "2 3" 4
不会起作用,因为在这种语法中 bash 会忽略双引号:
$ echo 1 "2 3" 4
1 2 3 4
Run Code Online (Sandbox Code Playgroud)