更新时间:2023-11-18 09:10:22
首先stdin是文件描述符0(零)而不是1(stdout).
您可以像这样有条件地复制文件描述符或使用文件名:
[[ some_condition ]] && exec 3<"$filename" || exec 3<&0
some_long_command_line <&3
请注意,如果条件为错误的或,则显示的命令将执行第二个exec
,第一个exec
失败.如果您不想这样做,那么应该使用if
/else
:
if [[ some_condition ]]
then
exec 3<"$filename"
else
exec 3<&0
fi
,但是如果第一次重定向失败(在条件为真之后),则随后从文件描述符3进行的重定向将失败.
I was trying to do this to decide whether to redirect stdin to a file or not:
[ ...some condition here... ] && input=$fileName || input="&0"
./myScript < $input
But that doesn't work because when the variable $input is "&0", bash interprets it as a filename.
However, I could just do:
if [ ...condition... ];then
./myScript <$fileName
else
./myScript
The problem is that ./myScript is actually a long command line that I don't want to duplicate, nor do I want to create a function for it because it's not that long either (it's not worth it).
Then it occurred to me to do this:
[ ...condition... ] && input=$fileName || input= #empty
cat $input | ./myScript
But that requires to run one more command and a pipe (i.e. a subshell).
Is there another way that's simpler and more efficient?
First of all stdin is file descriptor 0 (zero) rather than 1 (which is stdout).
You can duplicate file descriptors or use filenames conditionally like this:
[[ some_condition ]] && exec 3<"$filename" || exec 3<&0
some_long_command_line <&3
Note that the command shown will execute the second exec
if either the condition is false or the first exec
fails. If you don't want a potential failure to do that then you should use an if
/ else
:
if [[ some_condition ]]
then
exec 3<"$filename"
else
exec 3<&0
fi
but then subsequent redirections from file descriptor 3 will fail if the first redirection failed (after the condition was true).