在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和tail。问题在于流程替换问题:<(...)
有人可以告诉我这里有什么不同吗?
[编辑]
感谢您的回答!
使用 capistrano 进行部署时出现问题。它默认使用 sh ,但我现在将其更改为 bash 。
我无法正常管道的原因是当使用tail -F | grep -q --line-buffered
时,grep不会在匹配后立即退出。必须再对该文件进行一次编辑,例如echo "" >> catalina.out
,这在我的情况下是不可接受的。
答案 0 :(得分:5)
语法<(...)
仅由BASH支持。
对于任何POSIX shell,请使用以下方法:
sh -c 'tail -n 1000 -F catalina.out | if grep -qP --line-buffered ".+" ; then ...'
即。用管道移动if
前面的stdin重定向。 if
会将标准输入传递给grep
。
if tail ...| grep
无法使用,因为if
将无法看到它then
/ fi
,因为管道会分隔进程。
答案 1 :(得分:5)
您应该注意POSIX没有指定进程替换(<(...)
)。因此,如果您在POSIX模式下运行bash
,请使用sh
调用它,或者说:
set -o posix
然后你会发现错误!
来自bash manual:
使用
--posix
命令行选项启动Bash或执行“set
当Bash运行时,-o posix
'会使Bash更符合POSIX标准,方法是改变行为以匹配 由POSIX在Bash默认值不同的区域中指定。...
无法使用流程替代。
答案 2 :(得分:3)
另请注意如果Bash is invoked with the name sh,它会尽可能地模仿sh历史版本的启动行为,同时也符合POSIX标准。
如果你的sh实际上是bash的链接,那么这就是造成这种情况的原因。
运行sh --version; sh -c ': <(echo a)'
应该会为您提供足够的信息。