zsh 重定向,连同参数扩展
zsh redirection, together with parameter expansion
我正在编写一个 shell 调用程序 P 的脚本 S。
P 只接受来自标准输入的输入。
我的脚本S有一个参数是可选的;如果参数存在,它表示一个文件,应该被送入P。如果参数丢失,S的stdin应该被送入P。
这是我尝试解决的问题:
P <${3:-&0}
想法是:如果(第 3 个)参数是文件名,比如:foo,它应该执行
P <foo
但如果缺少或为空,则应执行
P <&0
根据我的理解,这应该等同于
P
即从标准输入读取。但是,这不起作用。从字面上使用 <&0 时,可以工作,如
echo abc|cat <&0
它会产生错误消息 no such file or directory: &0 当以我在脚本中的方式使用时。这让我感到惊讶,因为我从 zsh 手册页中了解到参数扩展发生在设置重定向之前。
我当然可以使用这个技巧
cat |P
但这看起来不太优雅。
有人可以向我解释一下,为什么我的方法不起作用,在这里使用什么成语比较好?
参数扩展发生在重定向之前,但这没有帮助。 <&0
是 <&<em>[NUMBER]</em>
运算符,而 <${…}
是 <
运算符后跟${…}
运算符将 <
解释为文件名的单词。如果文件名以 &
.
开头,则没有特殊情况会改变含义
您可以使用 exec
内置函数来设置重定向,而不是其他任何东西,以避免重复代码。当命令是外部命令时,这很有效。
( if [[ -n ]]; then exec <; fi;
exec P )
如果您需要 P
在外部上下文(而不是子 shell)中执行,另一种方法是使用中间文件描述符设置重定向。
if [[ -n ]]; then exec 9<; else exec 9<&0; fi
P <&9
exec 9<&-
或者,定义一个函数以避免代码重复。
P () { … }
if [[ -n ]]; then P <; else P; fi
我正在编写一个 shell 调用程序 P 的脚本 S。
P 只接受来自标准输入的输入。
我的脚本S有一个参数是可选的;如果参数存在,它表示一个文件,应该被送入P。如果参数丢失,S的stdin应该被送入P。
这是我尝试解决的问题:
P <${3:-&0}
想法是:如果(第 3 个)参数是文件名,比如:foo,它应该执行
P <foo
但如果缺少或为空,则应执行
P <&0
根据我的理解,这应该等同于
P
即从标准输入读取。但是,这不起作用。从字面上使用 <&0 时,可以工作,如
echo abc|cat <&0
它会产生错误消息 no such file or directory: &0 当以我在脚本中的方式使用时。这让我感到惊讶,因为我从 zsh 手册页中了解到参数扩展发生在设置重定向之前。
我当然可以使用这个技巧
cat |P
但这看起来不太优雅。
有人可以向我解释一下,为什么我的方法不起作用,在这里使用什么成语比较好?
参数扩展发生在重定向之前,但这没有帮助。 <&0
是 <&<em>[NUMBER]</em>
运算符,而 <${…}
是 <
运算符后跟${…}
运算符将 <
解释为文件名的单词。如果文件名以 &
.
您可以使用 exec
内置函数来设置重定向,而不是其他任何东西,以避免重复代码。当命令是外部命令时,这很有效。
( if [[ -n ]]; then exec <; fi;
exec P )
如果您需要 P
在外部上下文(而不是子 shell)中执行,另一种方法是使用中间文件描述符设置重定向。
if [[ -n ]]; then exec 9<; else exec 9<&0; fi
P <&9
exec 9<&-
或者,定义一个函数以避免代码重复。
P () { … }
if [[ -n ]]; then P <; else P; fi