为何service --status-all管道传输至grep时会输出多余无关行?
异常产生原因
你观察到的异常来自两个独立的问题,其中直接导致无关行出现的是shell流的默认传递规则问题,另外你的正则写法还存在潜在的匹配误差:
- 前两行带
[ ? ]的内容完全不是grep的匹配输出。service --status-all运行时,无法确定运行状态的服务(即标记为?的条目)相关信息会输出到标准错误流(stderr,文件描述符2),而shell管道|默认仅会转发前序命令的标准输出流(stdout,文件描述符1) 给后续命令,stderr内容不会进入grep的处理流程,会直接打印到当前终端。这两行内容里根本不存在php关键字,grep不可能输出完全不匹配模式的行,也能佐证这一点。 - 你写的正则存在语法缺陷:扩展正则规则中,未转义的
.是通配符,可以匹配任意单个字符,你写的php[0-9]+.[0-9]+会误匹配php7x4、php8-2这类不符合PHP版本格式的字符串,只是当前测试环境的输出里刚好没有触发这类误匹配。
验证方式
执行以下命令将service命令的stderr重定向到空设备(即屏蔽直接打印到终端的错误流内容),就会发现前两行无关内容直接消失:
sudo service --status-all 2>/dev/null | grep -oE 'php[0-9]+.[0-9]+'
适配脚本场景的正确命令
要稳定提取系统中已安装的PHP版本号、避免脚本因为版本变动或输出杂项失效,需要做两处修正:一是屏蔽service命令的stderr杂项输出,二是转义正则中的点号,让它仅匹配版本号中的真实小数点,额外可以加去重逻辑避免重复输出相同版本:
sudo service --status-all 2>/dev/null | grep -oE 'php[0-9]+\.[0-9]+' | sort -u
输出结果可以直接通过变量捕获写入配置,不会被杂项内容干扰。
内容的提问来源于stack exchange,提问作者siralbert
相关产品推荐
相关产品推荐

