如何在 python 脚本中使用名称 ("Web Content") 中的 space pkill 进程
How to pkill process with a space in the name ("Web Content") in a python script
美好的一天,这应该是相当简单的,但我的谷歌搜索和实验不起作用。
我在 python 中有一个抓取脚本,它使用 Selenium/geckodriver/Firefox 运行 在 Ubuntu 18 服务器上。有时它没有正确关闭,Selenium 会在脚本中崩溃,但它会使许多 Web Content
进程处于打开状态。如果不关闭,它们会耗尽所有内存,然后 selenium 将无法再打开,脚本将失败。
如果我从命令行 运行:pkill 'Web Content'
它将终止那些进程并释放内存。
在我的 python 脚本中,我使用 subprocess
模块尝试在 Selenium 崩溃时自动执行此操作。我尝试了多种选择,包括:
subprocess.call("pkill 'Web Content'".split())
subprocess.call("pkill 'Web\ Content'".split())
subprocess.call("pkill Web\ Content".split())
subprocess.call("pkill -f Web\ Content".split())
所有这些都抛出相同的错误:pkill: only one pattern can be provided
然而,如果我执行类似 subprocess.call("pkill firefox".split())
的操作,代码能够 运行 而不会出错。
我必须怎么做才能解决这个问题?谢谢。
您有 2 个选择:
使用subprocess.call("pkill 'Web Content'", shell=True)
或
subprocess.call(shlex.split("pkill 'Web Content'"))
选项 1
来自docs:
On POSIX with shell=True, the shell defaults to /bin/sh. If args is a
string, the string specifies the command to execute through the shell.
This means that the string must be formatted exactly as it would be
when typed at the shell prompt.
split()
围绕空格拆分 Python 字符串:
>>> "pkill 'Web Content'".split()
['pkill', "'Web", "Content'"]
所以 subprocess.call("pkill 'Web Content'".split())
为 pkill
提供了两个参数:"'Web"
和 "Content'"
而它只需要一个。这就是错误 pkill: only one pattern can be provided
弹出的原因。
注意 subprocess.call
signature 相当于 subprocess.Popen
:
subprocess.Popen(args,..
来自docs:
args should be a sequence of program arguments or else a single string
or path-like object. By default, the program to execute is the first
item in args if args is a sequence.
在使用 shell=True
时还要注意 security considerations
选项 2
如果要提供 args 序列,请使用 shlex.split
:
>>> s = "pkill 'Web Content'"
>>> import shlex
>>> args = shlex.split(s)
>>> import subprocess
>>> subprocess.call(args)
shlex.split
将 split 字符串 s
使用 shell-like 语法。
使用哪个选项由你决定,注意这里的相关信息answer:
Understand shell=True vs shell=False With shell=True you pass a single
string to your shell, and the shell takes it from there.
With shell=False you pass a list of arguments to the OS, bypassing the
shell.
When you don't have a shell, you save a process and get rid of a
fairly substantial amount of hidden complexity, which may or may not
harbor bugs or even security problems.
On the other hand, when you don't have a shell, you don't have
redirection, wildcard expansion, job control, and a large number of
other shell features.
自己手动拆分命令行可以显着简化整个问题。
subprocess.run(['pkill', 'Web Content'], check=True)
如果您确实需要 Python 执行拆分,shlex.split()
会执行您假定 Python 的常规 split
函数会遵守的规则。它没有;它只是根据您提供的字符串进行拆分,不支持转义等。
美好的一天,这应该是相当简单的,但我的谷歌搜索和实验不起作用。
我在 python 中有一个抓取脚本,它使用 Selenium/geckodriver/Firefox 运行 在 Ubuntu 18 服务器上。有时它没有正确关闭,Selenium 会在脚本中崩溃,但它会使许多 Web Content
进程处于打开状态。如果不关闭,它们会耗尽所有内存,然后 selenium 将无法再打开,脚本将失败。
如果我从命令行 运行:pkill 'Web Content'
它将终止那些进程并释放内存。
在我的 python 脚本中,我使用 subprocess
模块尝试在 Selenium 崩溃时自动执行此操作。我尝试了多种选择,包括:
subprocess.call("pkill 'Web Content'".split())
subprocess.call("pkill 'Web\ Content'".split())
subprocess.call("pkill Web\ Content".split())
subprocess.call("pkill -f Web\ Content".split())
所有这些都抛出相同的错误:pkill: only one pattern can be provided
然而,如果我执行类似 subprocess.call("pkill firefox".split())
的操作,代码能够 运行 而不会出错。
我必须怎么做才能解决这个问题?谢谢。
您有 2 个选择:
使用subprocess.call("pkill 'Web Content'", shell=True)
或
subprocess.call(shlex.split("pkill 'Web Content'"))
选项 1
来自docs:
On POSIX with shell=True, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt.
split()
围绕空格拆分 Python 字符串:
>>> "pkill 'Web Content'".split()
['pkill', "'Web", "Content'"]
所以 subprocess.call("pkill 'Web Content'".split())
为 pkill
提供了两个参数:"'Web"
和 "Content'"
而它只需要一个。这就是错误 pkill: only one pattern can be provided
弹出的原因。
注意 subprocess.call
signature 相当于 subprocess.Popen
:
subprocess.Popen(args,..
来自docs:
args should be a sequence of program arguments or else a single string or path-like object. By default, the program to execute is the first item in args if args is a sequence.
在使用 shell=True
选项 2
如果要提供 args 序列,请使用 shlex.split
:
>>> s = "pkill 'Web Content'"
>>> import shlex
>>> args = shlex.split(s)
>>> import subprocess
>>> subprocess.call(args)
shlex.split
将 split 字符串 s
使用 shell-like 语法。
使用哪个选项由你决定,注意这里的相关信息answer:
Understand shell=True vs shell=False With shell=True you pass a single string to your shell, and the shell takes it from there.
With shell=False you pass a list of arguments to the OS, bypassing the shell.
When you don't have a shell, you save a process and get rid of a fairly substantial amount of hidden complexity, which may or may not harbor bugs or even security problems.
On the other hand, when you don't have a shell, you don't have redirection, wildcard expansion, job control, and a large number of other shell features.
自己手动拆分命令行可以显着简化整个问题。
subprocess.run(['pkill', 'Web Content'], check=True)
如果您确实需要 Python 执行拆分,shlex.split()
会执行您假定 Python 的常规 split
函数会遵守的规则。它没有;它只是根据您提供的字符串进行拆分,不支持转义等。