在Centos 6机器上,这是有效的:
bash -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
这不:
sh -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
我得到:
sh: -c: line 0: syntax error near unexpected token `(' sh: -c: line 0: `if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
没关系,grep和尾巴。 问题在于进程replacethingy: <(...)
有人能告诉我什么sh在这里有所不同吗?
[编辑]
感谢您的答案!
使用Capistrano进行部署时出现问题。 它默认使用sh,但我改变了现在bash 。 我无法做正常的pipe道的原因是,当使用tail -F | grep -q --line-buffered
tail -F | grep -q --line-buffered
,grep在匹配后不会立即退出。 echo "" >> catalina.out
这个文件必须多一个编辑,这在我的情况下是不能接受的。
语法<(...)
仅由BASH支持。
对于任何POSIX shell,使用这种方法:
sh -c 'tail -n 1000 -F catalina.out | if grep -qP --line-buffered ".+" ; then ...'
即将标准输入重定向移动到if
前面的管道。 if
将stdin传递给grep
。
if tail ...| grep
if tail ...| grep
将无法工作,因为if
将不能看到它的/ fi
因为管道分离进程。
您应该注意,进程替换( <(...)
)不是由POSIX指定的。 所以如果你用sh
调用bash
或者说:
set -o posix
那么你会发现错误!
从bash手册 :
在Bash运行时使用
--posix
命令行选项启动Bash或者执行'set
-o posix
'将使Bash更符合POSIX标准,方法是更改行为以匹配POSIX在Bash默认值不同。…
过程替换不可用。
另外要注意的是, 如果Bash被引用了sh这个名字 ,它就尽可能地模仿sh历史版本的启动行为,同时也符合POSIX标准。
如果你的sh实际上是bash的链接,那么这就是造成这种情况的原因。
运行sh --version; sh -c ': <(echo a)'
sh --version; sh -c ': <(echo a)'
会给你足够的信息。