Python使用标志和管道运行bash脚本

时间:2018-08-23 21:29:37

标签: python bash subprocess

我有一个bash脚本,可以返回域的管理电子邮件,如下所示。

whois -h $(whois "stackoverflow.com" | grep 'Registrar WHOIS Server:' | cut -f2- -d:) "stackoverflow.com" | grep 'Admin Email:' | cut -f2- -d:

我想在python文件中运行它。我相信我需要使用一个子进程,但似乎无法使其与管道和标志一起使用。有帮助吗?

3 个答案:

答案 0 :(得分:1)

是的,您可以对管道使用子流程。 我将举例说明:

ps = subprocess.Popen(('whois', 'stackoverflow.com'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'Registrar WHOIS'), stdin=ps.stdout)
ps.wait()

您可以根据需要进行调整

答案 1 :(得分:0)

最简单的解决方案是将命令写入脚本文件并执行该文件。

如果您不想这样做,可以执行以下任何命令

bash -c 'command'

答案 2 :(得分:0)

文档的Replacing Older Functions with the subprocess Module部分对此进行了介绍。

有bash管道的示例:

output=`dmesg | grep hda`

subprocess改写为;

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

请注意,在许多情况下,您不需要以完全相同的方式处理外壳处理的所有相同边沿情况。但是,如果您不知道需要什么,最好像这样完全笼统。

您的$()与该示例中的反引号相同,您的管道与该示例的管道相同,并且您的参数没有什么特别的。

所以:

whois = Popen(['whois', 'stackoverflow.com'], stdout=PIPE)
grep = Popen(['grep', 'Registrar WHOIS Server:'], stdin=whois.stdout, stdout=PIPE)
whois.stdout.close()
cut = Popen(['cut', '-f2-', '-d:'], stdin=grep.stdout, stdout=PIPE)
grep.stdout.close()
inneroutput, _ = cut.communicate()
whois = Popen(['whois', '-h', inneroutput, 'stackoverflow.com'], stdout=PIPE)
grep = Popen(['grep', 'Admin Email:', stdin=whois.stdout, stdout=PIPE)
whois.stdout.close()
cut = Popen(['cut', '-f2-', '-d:'], stdin=grep.stdout)
grep.stdout.close()
cut.communicate()

如果这看起来一团糟,请考虑:

  • 您原来的shell命令是一团糟。
  • 如果您确实确切地知道管道将要执行的操作,则可以跳过很多。
  • 您在此处执行的所有操作都可以直接在Python中完成,而无需整个过程。
  • 使用诸如plumbum之类的第三方库可能会更快乐。

如果没有所有这些管道,如何用Python编写整个内容?例如,可以使用Python的grep模块来代替使用re。或者,由于您根本没有使用正则表达式,因此只需进行简单的in检查。对于cut同样如此:

whois = subprocess.run(['whois', 'stackoverflow.com'], 
                       check=True, stdout=PIPE, encoding='utf-8').output
for line in whois.splitlines():
    if 'Registrar WHOIS Server:' in line:
        registrar = line.split(':', 1)[1]
        break
whois = subprocess.run(['whois', '-h', registrar, 'stackoverflow.com'],
                       check=True, stdout=PIPE, encoding='utf-8').output
for line in inner.splitlines():
    if 'Admin Email:' in line:
        admin = line.split(':', 1)[1]
        break