Bash命令替换异常:跨主机日志查询中grep的问题解决
解决方案
以下几种单命令方案可以解决你的问题:
方法1:用find -exec直接调用grep(推荐)
直接让find找到文件后执行grep,完全避免文件名传递的问题,没有匹配文件时不会触发grep,自然不会挂起:
ssh SOME_HOST 'find SOME_PATH -type f -name "*.log" -exec grep "SOME_VALUE" {} +'
{} +会把所有匹配到的文件一次性传给grep,和直接在命令行写多个文件名效果一致,效率也高。如果需要每个文件单独显示匹配结果(比如带文件名前缀),可以把+换成\;,不过+的性能更优。
方法2:用xargs处理find的输出
通过xargs把find输出的文件名转换成grep的参数,没有匹配文件时xargs不会运行grep,避免挂起:
ssh SOME_HOST 'find SOME_PATH -type f -name "*.log" | xargs grep "SOME_VALUE"'
如果日志文件名包含空格或特殊字符,改用-print0和-0来兼容:
ssh SOME_HOST 'find SOME_PATH -type f -name "*.log" -print0 | xargs -0 grep "SOME_VALUE"'
原命令问题解析
- 不带双引号的写法:当
find没有输出时,命令退化为grep "SOME_VALUE",此时grep会等待标准输入,导致永久挂起。 - 带双引号的写法:
find输出的多个文件名以换行分隔,被双引号包裹后会被当成一个包含换行符的整体文件名,grep无法找到这个不存在的文件,因此报错。
内容的提问来源于stack exchange,提问作者OM222O
相关产品推荐
相关产品推荐

