python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道)
后台-插件-广告管理-内容页头部广告(手机) |
文章目录
- python subprocess
- 基本函数
- subprocess.run
- 示例(只可以捕获标准输出,标准错误不知道咋获取,异常也没抛。。。以后再看,现在有事)
- subprocess.Popen
- subprocess.Popen参数解释
- - `args`:要执行的命令及其参数。可以是一个字符串或一个字符串列表。
- - `bufsize`:指定缓冲区的大小。默认值为-1,表示使用系统默认的缓冲区大小。
- - `executable`:指定要执行的可执行文件的路径。默认值为None,表示使用系统默认的可执行文件。
- - `stdin`:指定子进程的标准输入。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输入。
- - `stdout`:指定子进程的标准输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输出。
- - `stderr`:指定子进程的标准错误输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准错误输出。
- - `preexec_fn`:在子进程执行前调用的可调用对象。默认值为None,表示不调用任何函数。
- 示例:使用preexec_fn来将Popen对象绑定进程组
- - `close_fds`:指定是否在子进程中关闭父进程中打开的文件描述符。默认值为True,表示关闭文件描述符。
- - `shell`:指定是否通过shell来执行命令。默认值为False,表示不通过shell执行命令。
- 使用shell执行和不使用shell执行的差异(以管道为例)
- - `cwd`:指定子进程的当前工作目录。默认值为None,表示使用父进程的当前工作目录。
- - `env`:指定子进程的环境变量。可以是一个字典,表示环境变量的键值对。默认值为None,表示使用父进程的环境变量。
- - `universal_newlines`:指定是否将输入/输出流以文本模式打开。默认值为False,表示以二进制模式打开。
- - `startupinfo`:指定子进程的启动信息。可以是一个subprocess.STARTUPINFO对象,用于设置子进程的一些属性。默认值为None。
- - `creationflags`:指定子进程的创建标志。默认值为0,表示使用默认的创建标志。
- - `restore_signals`:指定是否在子进程中恢复信号处理程序。默认值为True,表示恢复信号处理程序。
- - `start_new_session`:指定是否在新的会话中启动子进程。默认值为False,表示在当前会话中启动子进程。
- - `pass_fds`:指定要传递给子进程的文件描述符列表。默认值为(),表示不传递文件描述符。
- - `encoding`:指定输入/输出的编码方式。默认值为None,表示使用系统默认的编码方式。
- - `errors`:指定输入/输出的错误处理方式。默认值为None,表示使用系统默认的错误处理方式。
- 总结
- Popen对象的常用方法和属性
- subprocess.check_output
%20
python%20subprocess
%20Python的subprocess模块是用于创建和管理子进程的模块。它提供了一种在Python中调用外部命令的方式,可以执行系统命令、启动新的进程、连接到子进程的输入/输出管道等。
%20基本函数
%20subprocess.run
%20 subprocess.run(args,%20*,%20stdin=None,%20input=None,%20stdout=None, %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stderr=None,%20capture_output=False,%20text=None, %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20check=False,%20timeout=None,%20encoding=None,%20errors=None)- 1
- 2
- 3
- 运行指定的命令,并等待其完成。args参数是一个字符串或列表,表示要执行的命令和参数。
- stdin、stdout和stderr参数分别用于指定子进程的标准输入、标准输出和标准错误输出的处理方式。
- capture_output参数用于指定是否捕获子进程的输出。
- check参数用于指定是否检查子进程的返回值,如果返回值不为0,则会抛出CalledProcessError异常。
- timeout参数用于指定子进程的超时时间。
- encoding和errors参数用于指定输入/输出的编码方式和错误处理方式。
示例(只可以捕获标准输出,标准错误不知道咋获取,异常也没抛。。。以后再看,现在有事)
%20 import%20subprocess def%20execute_update_ip_sh(ip): %20%20%20%20""" %20%20%20%20执行修改配置文件%20ip%20脚本,将会修改ky_ai_solution.json、nginx.conf、vsftpd.conf%20等文件中的ip %20%20%20%20""" %20%20%20%20try: %20%20%20%20%20%20%20%20#%20构建命令 %20%20%20%20%20%20%20%20command%20=%20['/ky/update_ip.sh',%20ip] %20%20%20%20%20%20%20%20#%20执行命令并获取输出(这个出错直接就抛异常了,不能捕获标准输出和标准错误) %20%20%20%20%20%20%20%20#%20result%20=%20subprocess.check_output(command,%20universal_newlines=True) %20%20%20%20%20%20%20%20result%20=%20subprocess.run(command,%20stdout=subprocess.PIPE, %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stderr=subprocess.PIPE,%20universal_newlines=True) %20%20%20%20%20%20%20%20#%20打印脚本的输出 %20%20%20%20%20%20%20%20print(f"[{command}]%20标准输出:",%20result.stdout) %20%20%20%20%20%20%20%20#%20打印脚本的错误输出(打印不出来) %20%20%20%20%20%20%20%20print(f"[{command}]%20标准错误输出:",%20result.stderr) %20%20%20%20%20%20%20%20#%20执行成功,返回True %20%20%20%20%20%20%20%20return%20result.returncode%20==%200 %20%20%20%20#%20except%20subprocess.CalledProcessError%20as%20e: %20%20%20%20except%20Exception%20as%20e: %20%20%20%20%20%20%20%20#%20执行失败,返回False %20%20%20%20%20%20%20%20print(e) %20%20%20%20%20%20%20%20print("ddddddddddddddddddddddddddddddddddddddd") %20%20%20%20%20%20%20%20return%20False if%20__name__%20==%20"__main__": %20%20%20%20execute_update_ip_sh("192.168.1.140")- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
subprocess.Popen
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 启动一个新的进程,并返回一个Popen对象,可以用于与子进程进行交互。
- args参数和其他参数的含义与subprocess.run()函数相同。
subprocess.Popen参数解释
- args:要执行的命令及其参数。可以是一个字符串或一个字符串列表。
- bufsize:指定缓冲区的大小。默认值为-1,表示使用系统默认的缓冲区大小。
- executable:指定要执行的可执行文件的路径。默认值为None,表示使用系统默认的可执行文件。
- stdin:指定子进程的标准输入。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输入。
- stdout:指定子进程的标准输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输出。
- stderr:指定子进程的标准错误输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准错误输出。
- preexec_fn:在子进程执行前调用的可调用对象。默认值为None,表示不调用任何函数。
示例:使用preexec_fn来将Popen对象绑定进程组
当使用shell=True时,subprocess.Popen()函数创建的子进程实际上是一个shell进程,而不是直接执行的命令。因此,向Popen对象发送信号并不能直接影响到子进程。
如果需要向通过shell执行的命令发送信号,可以使用os.killpg()函数来发送信号给进程组。具体步骤如下:
- 创建Popen对象时,设置preexec_fn=os.setsid,以创建一个新的进程组。
- 使用os.killpg()函数发送信号给进程组。
下面是一个示例,演示了如何向通过shell执行的命令发送信号:
import subprocess import os import signal # 通过shell执行命令 process = subprocess.Popen('sleep 10', shell=True, preexec_fn=os.setsid) # 发送信号给进程组 os.killpg(os.getpgid(process.pid), signal.SIGTERM)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
在这个示例中,首先通过subprocess.Popen()函数创建了一个通过shell执行的命令。在创建Popen对象时,通过preexec_fn=os.setsid设置了preexec_fn参数,以创建一个新的进程组。
然后,使用os.killpg()函数发送信号给进程组。在这个示例中,发送了SIGTERM信号,即终止信号。
需要注意的是,向进程组发送信号会影响到进程组中的所有进程。因此,如果有多个通过shell执行的命令,它们都属于同一个进程组,发送信号时需要注意。
- close_fds:指定是否在子进程中关闭父进程中打开的文件描述符。默认值为True,表示关闭文件描述符。
- shell:指定是否通过shell来执行命令。默认值为False,表示不通过shell执行命令。
当shell参数设置为True时,表示通过shell来执行命令。这意味着可以使用shell的语法和功能,比如管道、重定向、通配符等。在这种情况下,args参数可以是一个字符串,表示要执行的完整命令。
当shell参数设置为False时,表示不通过shell来执行命令。这是默认的行为。在这种情况下,args参数应该是一个字符串列表,其中第一个元素是要执行的命令,后续元素是命令的参数。
需要注意的是,使用shell=True时,应该谨慎处理输入参数,避免命令注入等安全问题。应该始终对用户输入进行验证和过滤,避免直接将用户输入拼接到命令中。
下面是一个示例,演示了shell参数的用法:
import subprocess # 通过shell执行命令 subprocess.Popen('ls -l', shell=True) # 不通过shell执行命令 subprocess.Popen(['ls', '-l'])- 1
- 2
- 3
- 4
- 5
- 6
- 7
在这个示例中,第一个Popen()函数调用通过shell执行了ls -l命令,而第二个Popen()函数调用不通过shell执行了ls -l命令。
使用shell执行和不使用shell执行的差异(以管道为例)
- 使用shell执行:
下面是一个示例,演示了如何通过shell执行命令并使用管道:
import subprocess # 通过shell执行命令并使用管道 process = subprocess.Popen('ls -l | grep .txt', shell=True) # 等待子进程结束 process.wait()- 1
- 2
- 3
- 4
- 5
- 6
- 7
在这个示例中,通过subprocess.Popen()函数的shell参数设置为True,表示通过shell执行命令。然后,可以使用shell的管道语法|将两个命令连接起来,实现输出过滤。
- 不使用shell执行:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在这个示例中,首先创建了两个Popen()对象,分别对应两个命令。command1执行了ls -l命令,并将输出通过管道传递给command2。command2执行了grep .txt命令,并将结果输出到标准输出。
通过command2.communicate()方法获取命令2的输出,并将其打印出来。
不通过shell执行命令时,需要手动设置命令之间的输入输出关系,以及处理命令的输出。这需要更多的代码来实现,但也提供了更多的灵活性和控制能力。
- cwd:指定子进程的当前工作目录。默认值为None,表示使用父进程的当前工作目录。
- env:指定子进程的环境变量。可以是一个字典,表示环境变量的键值对。默认值为None,表示使用父进程的环境变量。
- universal_newlines:指定是否将输入/输出流以文本模式打开。默认值为False,表示以二进制模式打开。
- startupinfo:指定子进程的启动信息。可以是一个subprocess.STARTUPINFO对象,用于设置子进程的一些属性。默认值为None。
- creationflags:指定子进程的创建标志。默认值为0,表示使用默认的创建标志。
- restore_signals:指定是否在子进程中恢复信号处理程序。默认值为True,表示恢复信号处理程序。
- start_new_session:指定是否在新的会话中启动子进程。默认值为False,表示在当前会话中启动子进程。
- pass_fds:指定要传递给子进程的文件描述符列表。默认值为(),表示不传递文件描述符。
- encoding:指定输入/输出的编码方式。默认值为None,表示使用系统默认的编码方式。
- errors:指定输入/输出的错误处理方式。默认值为None,表示使用系统默认的错误处理方式。
总结
subprocess.Popen()函数会返回一个Popen对象,可以用于与子进程进行交互。Popen对象具有一些常用的方法和属性,比如communicate()、wait()、poll()、terminate()、kill()、stdout、stderr和returncode等。
Popen对象的常用方法和属性
- communicate(input=None, timeout=None):与子进程进行交互,发送输入并获取输出。
- wait():等待子进程结束,并返回其返回值。
- poll():检查子进程是否结束,如果结束则返回其返回值,否则返回None。
- terminate():终止子进程。
- kill():杀死子进程。
- stdout:子进程的标准输出。
- stderr:子进程的标准错误输出。
- returncode:子进程的返回值。
下面是一个使用subprocess模块的示例,演示了如何执行一个系统命令并获取其输出:
import subprocess # 执行系统命令 result = subprocess.run(['ls', '-l'], capture_output=True, text=True) # 获取命令的输出 output = result.stdout print(output)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
以上代码会执行ls -l命令,并将其输出打印出来。
需要注意的是,subprocess模块在执行外部命令时,存在一定的安全风险,特别是在使用shell=True参数时。因此,在使用subprocess模块时,应该谨慎处理输入参数,避免命令注入等安全问题。
subprocess.check_output
subprocess.check_output函数是Python标准库subprocess模块中的一个函数,用于执行系统命令并返回命令的输出结果。
它的用法是:
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)- 1
- 2
其中,args是一个字符串或者字符串列表,表示要执行的命令及其参数。stdin、stderr、shell和universal_newlines是可选参数,用于控制输入、错误输出、是否使用shell以及输出结果的编码方式。
check_output函数会执行指定的命令,并等待命令执行完成。如果命令执行成功,它会返回命令的输出结果(以字节字符串的形式),如果命令执行失败,它会抛出一个CalledProcessError异常。
在上述代码中,subprocess.check_output函数被用于执行一些系统命令,如ip addr show和ip route show,以获取当前以太网接口的IP配置信息。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |