用于包装嘈杂的python脚本并使用sed删除特定行的shell命令问题[重复]
Posted
技术标签:
【中文标题】用于包装嘈杂的python脚本并使用sed删除特定行的shell命令问题[重复]【英文标题】:Issue with shell command used to wrap noisy python script and remove specific lines with sed [duplicate] 【发布时间】:2016-01-27 01:27:55 【问题描述】:我正在使用一个 python 脚本,它基于完全正常的错误测试证书输出许多警告/错误(进入标准错误)。基于几个 SO 帖子,我能够找到一种方法来运行脚本并忽略 select stdout、stderr 行,但它很麻烦:
runThing 3>&1 1>&2 2>&3 3>&- | grep -r 's/Insecure/'
OR
runThing 3>&1 1>&2 2>&3 3>&- | sed 's/Insecure/g'
两者都过滤掉很多行,例如:
/Users/xxx/.blah/lib/python2.7/site- packages/requests/packages/urllib3/connectionpool.py:791: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html InsecureRequestWarning)
但是 sed 有这个错误: sed: 1: "s/Insecure/g": 正则表达式中未终止的替换
在一个经常使用的行的末尾添加了很多内容(真正的 runThing 有命令和参数),所以我试图制作一个类似的命令:
runThingClean() command runThing "$@" > /dev/null 3>&1 1>&2 2>&3 3>&- | sed 's/Insecure/g' &
当我运行它时,它现在无法过滤(并显示错误是使用了 sed):
sed: 1: "s/Insecure/g": unterminated substitute in regular expression
有人可以帮我解决这个命令吗?
提前谢谢..
【问题讨论】:
顺便说一句,您是否考虑过-W once
,最多打印一次每个警告?如果问题出在噪音水平上,那会让您感到相当满意。
【参考方案1】:
根本不要这样做:只要告诉 Python 一开始就不要打印警告,然后你就不需要过滤掉它们了。
python -W ignore yourprogram ...
或者,考虑修改调用相关组件的代码以抑制调用站点的警告,如given in the Python documentation:
import warnings
with warnings.catch_warnings():
warnings.simplefilter('ignore')
urllib3.doTheThingThatCausedTheWarning(...)
最后,如果你真的想在进程外作为过滤器,只需使用grep -v Insecure
; sed
的锤子比这项工作所需的要大。
sh -c 'printf "%s\n" "stderr: keep" "stderr: Insecure" >&2; echo "stdout"' \
3>&1 1>&2 2>&3 3>&- | grep -v Insecure 3>&1 1>&2 2>&3 3>&-
所有这些重定向所做的是交换 stdout 和 stderr 两次——一次在 grep 之前,一次在恢复它们之后。让我们看看它是如何工作的:
FD 1(原始标准输出)被复制到 FD 3(作为备份) FD 2(原始 stderr)被复制到 FD 1(因此可以过滤) FD 3(原始 stdout 的备份)被复制到 FD 2(现在存储在 stderr 中) FD 3 已关闭,因为交换完成后不再需要它。【讨论】:
感谢您的提示。不过,我希望不要抑制所有警告,并且无法修改代码。出于某种原因,这个: clean() command dirty "$@" > /dev/null 3>&1 1>&2 2>&3 3>&- | grep -v s/Insecure/ & 不会过滤其中包含 Insecure 的行。我想知道管道是否在工作? 您将 FD 1 重定向到/dev/null
,然后将 /dev/null
上的句柄复制到 FD 3?逻辑看起来不太对。
@chrismead, ...我在这里扩展了答案以提供一个经过测试的工作示例(在 grep 之后还将 stderr 和 stdout 移回其原始 FD)。
再次感谢@Charles Duffy。我现在正在尝试这个: clean() 命令嘈杂 "$@" 3>&1 1>&2 2>&3 3>&- | grep -v Insecure 3>&1 1>&2 2>&3 3>&- & 它仍然不起作用,但我想知道“嘈杂”是否运行另一个程序作为其操作的一部分。在这种情况下,可能 stdout、stdin、stderr 会有所不同?
@chrismead,不幸的是,取决于细节。如果您有直接将输出写入 TTY 的内容,您将无法在不使用 script
之类的东西将其返回到 stdout/stderr 的情况下对其进行过滤。【参考方案2】:
该错误表示您没有正确关闭sed
中的s
。对于s
,它应该是s/regex/substitution/g
如果您尝试删除 Insecure
或替换:
sed 's/Insecure/YOUR_SUBSTITUTION/g'
如果您尝试只显示带有Insecure
的行:
sed -n '/Insecure/p'
【讨论】:
感谢您的帮助。如果我这样做: clean() command dirty "$@" > /dev/null 3>&1 1>&2 2>&3 3>&- | sed 's/Insecure//g' & 我没有收到任何错误,但也没有删除包含 Insecure 的行。以上是关于用于包装嘈杂的python脚本并使用sed删除特定行的shell命令问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章