Get*_*ree 29 linux bash shell io-redirection
我试图这样做来决定是否将stdin重定向到文件:
[ ...some condition here... ] && input=$fileName || input="&0"
./myScript < $input
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为当变量$ input为"&0"时,bash会将其解释为文件名.
但是,我可以这样做:
if [ ...condition... ];then
./myScript <$fileName
else
./myScript
Run Code Online (Sandbox Code Playgroud)
问题是./myScript实际上是一个我不想复制的长命令行,也不想为它创建一个函数,因为它也不长(它不值得).
然后我突然想到这样做:
[ ...condition... ] && input=$fileName || input= #empty
cat $input | ./myScript
Run Code Online (Sandbox Code Playgroud)
但这需要再运行一个命令和一个管道(即子shell).
还有另一种更简单,更有效的方法吗?
Pau*_*ce. 24
首先,stdin是文件描述符0(零)而不是1(stdout).
您可以像这样有条件地复制文件描述符或使用文件名:
[[ some_condition ]] && exec 3<"$filename" || exec 3<&0
some_long_command_line <&3
Run Code Online (Sandbox Code Playgroud)
请注意,exec如果条件为false 或第一个exec失败,则显示的命令将执行第二个命令.如果您不希望有可能失败,那么您应该使用if/ else:
if [[ some_condition ]]
then
exec 3<"$filename"
else
exec 3<&0
fi
Run Code Online (Sandbox Code Playgroud)
但是如果第一次重定向失败(在条件为真之后),则后续文件描述符3的重定向将失败.
(
if [ ...some condition here... ]; then
exec <$fileName
fi
exec ./myscript
)
Run Code Online (Sandbox Code Playgroud)
在子shell中,有条件地重定向stdin并执行脚本.
标准输入也可以由特殊设备文件表示/dev/stdin,因此将其用作文件名将起作用.
file="/dev/stdin"
./myscript < "$file"
Run Code Online (Sandbox Code Playgroud)