问题
:
关于它在管道中的使用的语义是什么?
Bash文档指出:
: [arguments]
没有效果; 该命令除了扩展参数和执行任何指定的重定向之外什么都不做。返回状态为零。
:
但是,我应该期望在管道中使用什么行为并不明显。它只是通过吗std{in,out,err}
?
关于参数,:
似乎可以替代任何其他命令。但是我需要澄清一下在管道中的使用;澄清不仅基于观察,而且引用了权威来源。
背景
我有一种情况,根据脚本运行的环境,我需要运行输出以tr -d '\r'
从输出中删除回车符。
las,目前这意味着一个if/else/fi
块,沿着(函数内部):
if [[ "$OSTYPE" == "cygwin" ]]; then
my_commands | tr -d '\r' || return $?
else
my_commands || return $?
fi
其中 the是 the和branch| tr -d '\r'
之间的唯一区别。任何一个分支的内容当然比这里显示的要复杂得多。if
else
现在,我知道tr -d '\r'
在没有回车的情况下是良性的。但这是一个调用和(在 Windows 上)可以避免的开销(该函数是一个“热”代码路径)。所以我想到tr
用内置的 shell 函数代替:
。
在这种情况下,传递替换是
cat
,它将其输入复制到其输出。:
什么都不做,所以你的输入会丢失:事实上,由于
:
不读取它的输入,输入管道的命令将收到一个SIGPIPE
,因此它们可能无法完成任务,甚至无法启动它:使用
cat
意味着外部调用,就像tr
(但工作量稍少)。Bash 没有这种内置的传递。不管名字多么奇怪,
:
它仍然是一个命令并且像一个命令一样工作,所以当它什么都不做时,这意味着它也没有从管道中读取任何东西。从某种意义上说,它不是 shell 的特殊语法,| : |
可以减少到|
. 的 POSIX 描述:
确实说它不“使用”stdin 或 stdout,但当然它没有明确提到那里的管道。在Conditional pipeline中有一些解决方案,但大多数情况下,避免
cat
在中间运行副本是困难或尴尬的。(细则:POSIX 文本使用术语“实用程序”,但它仍然与用于 eg 的术语相同。另外
ls
,它:
不完全是一个常规命令,而是一个“特殊内置”,这在一些小的方面有所不同案例,但不是这里。)手册页中的关键短语是
:
(与其同义词一样true
)什么都不做。它不从其输入中读取任何内容,也不向其输出流写入任何内容。在管道中,它不是很有用 - 它就像管道中的堵塞物一样。