popen函数的用法,system函数和popen函数

http://www.itjxue.com  2023-01-15 00:32  来源:未知  点击次数: 

python os.system、os.popen、subprocess.Popen的区别

1、使用os.system("cmd")

这是最简单的一种方法,其执行过程中会输出显示cmd命令执行的信息。

例如:print os.system("mkdir test") 输出:0

可以看到结果打印出0,表示命令执行成功;否则表示失败(再次执行该命令,输出:子目录或文件 test 已经存在。1)。

2、使用os.popen("cmd")

通过os.popen()返回的是 file read 的对象,对其进行读取read()操作可以看到执行的输出

例如:print os.popen("adb shell ls /sdcard/ | findstr aa.png").read() 输出:aa.png(若aa.png存在,否则输出为空)

3、subprocess.Popen("cmd")

subprocess模块被推荐用来替换一些老的模块和函数,如:os.system、os.spawn*、os.popen*等

subprocess模块目的是 启动一个新的进程并与之通信 ,最常用是定义类Popen,使用Popen可以创建进程,并与进程进行复杂的交互。其函数原型为:

classsubprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

Popen非常强大,支持多种参数和模式,通过其构造函数可以看到支持很多参数。但Popen函数存在缺陷在于, 它是一个阻塞的方法 ,如果运行cmd命令时产生内容非常多,函数就容易阻塞。另一点, Popen方法也不会打印出cmd的执行信息 。

以下罗列常用到的参数:

args :这个参数必须是 字符串 或者是一个由 字符串成员的列表 。其中如果是一个字符串列表的话,那第一个成员为要运行的程序的路径以及程序名称;从第二个成员开始到最后一个成员为运行这个程序需要输入的参数。这与popen中是一样的。

bufsize: 一般使用比较少,略过。

executable: 指定要运行的程序,这个一般很少用到,因为要指定运行的程序在args中已经指定了。 stdin,stdout?,stderr: 分别代表程序的标准输入、标准输出、标准错误处理。可以选择的值有 PIPE , 已经存在的打开的文件对象 和 NONE 。若stdout是文件对象的话,要确保文件对象是处于打开状态。

shell:shell参数根据要执行的命令情况来定,如果将参数shell设为True,executable将指定程序使用的shell。在windows平台下,默认的shell由COMSPEC环境变量来指定。

php通过popen获取的一个命令的返回值如何分析出来

PHP 中的 popen() 函数

popen() 函数打开进程文件指针。

popen(command,mode)

参数说明

command 必需。规定要执行的命令。

mode 必需。规定连接模式。 可能的值:

r: 只读。

w: 只写 (打开并清空已有文件或创建一个新文件)

打开一个指向进程的管道,该进程由派生指定的 command 命令执行而产生。

返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss() 和 fwrite()。

若出错,则返回 false。

例如:

?php

$file = popen("/bin/ls","r");

//一些要执行的代码

pclose($file);

?

popen函数怎么创建进程的

popen使用FIFO管道执行外部程序。

#include stdio.h

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

popen 通过type是r还是w确定command的输入/输出方向,r和w是相对command的管道而言的。r表示command从管道中读入,w表示 command通过管道输出到它的stdout,popen返回FIFO管道的文件流指针。pclose则用于使用结束后关闭这个指针。

下面看一个例子:

/*******************************************************************************************

** Name:popen.c

** This program is used to show the usage of popen() .

** Author:zieckey,(zieckey@yahoo.com.cn)

** Date:2007/9/30 11:47

** All rights reserved!

*******************************************************************************************/

#include sys/types.h

#include unistd.h

#include stdlib.h

#include stdio.h

#include string.h

int main( void )

{

FILE *stream;

FILE *wstream;

char buf[1024];

memset( buf, '\0', sizeof(buf) );//初始化buf,以免后面写如乱码到文件中

stream = popen( "ls -l", "r" ); //将“ls -l”命令的输出 通过管道读取(“r”参数)到FILE* stream

wstream = fopen( "test_popen.txt", "w+"); //新建一个可写的文件

fread( buf, sizeof(char), sizeof(buf), stream); //将刚刚FILE* stream的数据流读取到buf中

fwrite( buf, 1, sizeof(buf), wstream );//将buf中的数据写到FILE *wstream对应的流中,也是写到文件中

pclose( stream );

fclose( wstream );

return 0;

}

[root@localhost src]# gcc popen.c

[root@localhost src]# ./a.out

[root@localhost src]# cat test_popen.txt

总计 128

-rwxr-xr-x 1 root root 5558 09-30 11:51 a.out

-rwxr-xr-x 1 root root 542 09-30 00:00 child_fork.c

-rwxr-xr-x 1 root root 480 09-30 00:13 execve.c

-rwxr-xr-x 1 root root 1811 09-29 21:33 fork.c

-rwxr-xr-x 1 root root 162 09-29 18:54 getpid.c

-rwxr-xr-x 1 root root 1105 09-30 11:49 popen.c

-rwxr-xr-x 1 root root 443 09-30 00:55 system.c

-rwxr-xr-x 1 root root 0 09-30 11:51 test_popen.txt

-rwxr-xr-x 1 root root 4094 09-30 11:39 test.txt

本文来自: () 详细出处参考:

请教C++程序如何捕获linux shell的输出

调用系统函数popen,利用管道实现输出的传送即可。

popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数。pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。如果 shell 不能被执行,则 pclose() 返回的终止状态与 shell 已执行 exit 一样。

type?参数只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 "r" 则文件指针连接到 command 的标准输出;如果 type 是 "w" 则文件指针连接到 command 的标准输入。

command?参数是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用-c 标志,shell 将执行这个命令。

popen?的返回值是个标准 I/O 流,必须由?pclose?来终止。前面提到这个流是单向的。所以向这个流写内容相当于写入该命令的标准输入;命令的标准输出和调用?popen?的进程相同。与之相反的,从流中读数据相当于读取命令的标准输出;命令的标准输入和调用?popen?的进程相同。

例程如下:

#include?cstdio

#include?unistd.h

#include?cstring

#include?cstdlib

int?main()

{

????FILE?*read_fp;

????char?buffer[BUFSIZ?+?1];

????int?chars_read;

????memset(buffer,?'\0',?sizeof(buffer));

????read_fp?=?popen?("uname?-a",?"r");

????if?(read_fp?!=?NULL)

????{

????????chars_read?=?fread(buffer,?sizeof(char),?BUFSIZ,?read_fp);

????????if?(chars_read??0)

????????{

????????????printf("Output?was:?\n?%s?\n",?buffer);

????????}

????????pclose(read_fp);

????????exit(EXIT_SUCCESS);

????}

????exit(EXIT_FAILURE);

}

运行结果如下:

PHP执行linux系统命令的常用函数使用说明

system函数

说明:执行外部程序并显示输出资料。

语法:string

system(string

command,

int

[return_var]);

返回值:

字符串

详细介绍:

本函数就像是

C

语中的函数

system(),用来执行指令,并输出结果。若是

return_var

参数存在,则执行

command

之后的状态会填入

return_var

中。同样值得注意的是若需要处理用户输入的资料,而又要防止用户耍花招破解系统,则可以使用

EscapeShellCmd()。若

PHP

以模块式的执行,本函数会在每一行输出后自动更新

Web

服务器的输出缓冲暂存区。若需要完整的返回字符串,且不想经过不必要的其它中间的输出界面,可以使用

PassThru()。

实例代码:

复制代码

代码如下:

?php

$last_line

=

system('ls',

$retval);

echo

'Last

line

of

the

output:

'

.

$last_line;

echo

'hr

/Return

value:

'

.

$retval;

?

exec函数

说明:执行外部程序。

语法:string

exec(string

command,

string

[array],

int

[return_var]);

返回值:

字符串

详细介绍:

本函数执行输入

command

的外部程序或外部指令。它的返回字符串只是外部程序执行后返回的最后一行;若需要完整的返回字符串,可以使用

PassThru()

这个函数。

要是参数

array

存在,command

会将

array

加到参数中执行,若不欲

array

被处理,可以在执行

exec()

之前呼叫

unset()。若是

return_var

array

二个参数都存在,则执行

command

之后的状态会填入

return_var

中。

值得注意的是若需要处理使用者输入的资料,而又要防止使用者耍花招破解系统,则可以使用

EscapeShellCmd()。

实例代码:

复制代码

代码如下:

?php

echo

exec('whoami');

?

popen函数

说明:打开文件。

语法:int

popen(string

command,

string

mode);

返回值:

整数

详细介绍:

本函数执行指令开档,而该文件是用管道方式处理的文件。用本函数打开的文件只能是单向的

(只能读或只能写),而且一定要用

pclose()

关闭。在文件操作上可使用

fgets()、fgetss()

fputs()。若是开档发生错误,返回

false

值。

实例代码:

复制代码

代码如下:

?

$fp

=

popen("/bin/ls","r"

);

?

PHP监控linux服务器负载

在实际项目的应用中,我们由于各种条件的现实,利用PHP来实现服务器负载监控将是一种更为灵活的方式。

由于Web

Server以及PHP的实现方式所限,我们在现实环境中很难利用PHP去调用一些Linux中需要root权限才能执行的程序,对此,我从网上找到另外一种方式来绕开这个限制。首先先写个c程序中转调用系统命令,然后用PHP去执行此c程序。

c程序

首先写个c文件,比如/usr/local/ismole/w.c

复制代码

代码如下:

#includestdio.h

#includestdlib.h

#includesystypes.h

#includeunistd.h

int

main()

{

uid_t

uid

,euid;

//note

获得当前的uid

uid

=

getuid();

//note

获得当前euid

euid

=

geteuid();

//note

交换这两个id

if(setreuid(euid,

uid))

perror("setreuid");

//note

执行将要执行linux系统命令

system("/usr/bin/w");

return0;

}

编译该文件gcc

-o

w

-Wall

w.c,这时会在当前目录下生成程序w。改变此程序的属主chmod

u+s

./w。

PHP执行

文件内容如下,放在web目录下,访问就会输出当前的服务器负载情况。

复制代码

代码如下:

?php

/*

More

Original

PHP

Framwork

Copyright

(c)

2007

-

2008

IsMole

Inc.

$Id:

serverMonitor.php

408

2008-12-02

08:07:40Z

kimi

$

*/

//note

key的验证过程

if($key

!=

$authkey)

{

//

exit('key

error);

}

$last_line

=

exec('/usr/local/ismole/w',

$retval);

$returnArray

=

explode("load

average:

",

$retval[0]);

$returnString

=

$returnArray[1];

echo

$returnString; 

 按照上面的实例,我们可以用PHP来做任何我们想执行的Linux系统命令,SVN更新,服务器监控,备份,恢复,日常维护等等。

subprocess的popen函数

subprocess的进程创建和管理由Popen类处理。原型: (原型中参数带有的值都是默认值)

class? 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=None ,? startupinfo=None ,? creationflags=0 ,? restore_signals=True ,? start_new_session=False ,? pass_fds=() ,? * ,? group=None ,? extra_groups=None ,? user=None ,? umask=-1 ,? encoding=None ,? errors=None ,? text=None )

args参数: 一个需要运行的参数序列;默认情况下,如果args是序列,则运行的程序是这个序列中的第一项,比如[“python”,“--version”],运行的cmd就是这个列表中的第一项python;但是如果args是字符串,具体如何实现依赖于具体平台。如果在Windows 上? shell ?为?False?并且序列包含字节串和路径类对象则? args ?形参可以接受一个? path-like object 。 参数? shell ?(默认为?False)指定是否使用 shell 执行程序。如果? shell ?为?True,更推荐将? args ?作为字符串传递而非序列。 如果? args ?是一个字符串,则字符串的格式必须和在命令行中所输出的完全相同。在 Windows,使用? shell=True,环境变量?COMSPEC?指定了默认 shell。在 Windows 唯一需要指定?shell=True?的情况是想要执行内置在 shell 中的命令(例如? dir ?或者? copy )。在运行一个批处理文件或者基于控制台的可执行文件时,不需要?shell=True。

def cmd_run(cmd):

? ? print("the cmd is {}".format(cmd))

? ?subproc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, shell=True ) #设置shell为true

? ? while True:

? ? ? ? out = subproc.stdout.readline()

? ? ? ? if out:

? ? ? ? ? ? print(out)

? ? ? ? else:

? ? ? ? ? ? break

cmd_run("dir")

输出:

如果没有设置shell为True,则在windows上无法运行这个cmd。

executable ?参数 指定一个要执行的替换程序,比较少用到这个参数。当?shell=True,? executable ?替换? args ?指定运行的程序。但是,原始的? args ?仍然被传递给程序。

在 3.6 版更改:?在POSIX 上? executable ?形参可以接受一个? path-like object 。

在 3.8 版更改:?在Windows 上? executable ?形参可以接受一个字节串和? path-like object 。

stdin ,? stdout ?和? stderr ?分别指定被运行的程序的标准输入、输出和标准错误的文件句柄。合法的值有? PIPE ?,? DEVNULL ?, 一个存在的文件描述符(一个正整数),一个存在的? 文件对象 ?以及?None。? PIPE ?表示应创建一个新的对子进程的管道。? DEVNULL ?表示使用特殊的? os.devnull ?文件。使用默认的?None,则不进行成定向;子进程的文件流将继承自父进程。另外,? stderr ?可设为? STDOUT ,表示应用程序的标准错误数据应和标准输出一同捕获。

如果? close_fds ?为真 ,所有文件描述符除了?0,?1,?2?之外都会在子进程执行前关闭。而当? close_fds ?为假时,文件描述符遵守它们继承的标志如? 文件描述符的继承 ?所述。在 Windows,如果? close_fds ?为真, 则子进程不会继承任何句柄,除非在? STARTUPINFO.IpAttributeList 的? handle_list的键中显式传递,或者通过标准句柄重定向传递。

如果? cwd ?不为?None,此函数在执行子进程前会将当前工作目录改为? cwd 。? cwd ?可以是一个字符串、字节串或? 路径类对象 ?。 特别地,当可执行文件的路径为相对路径时,此函数会相对于*cwd* 来查找? executable ?(或? args ?中的第一个条目)。

在 3.6 版更改:?在 POSIX 上? cwd ?形参接受一个? path-like object 。

在 3.7 版更改:?在 Windows 上? cwd ?形参接受一个? path-like object 。

在 3.8 版更改:?在 Windows 上? cwd ?形参接受一个字节串对象。

如果? encoding ?或? errors ?被指定,或者? text ?为 true,则文件对象? stdin ,? stdout ?和? stderr ?将会以指定的编码和? errors ?以文本模式打开 ,如同? 常用参数 ?所述。?

universal_newlines ?参数 等同于? text ?并且提供向后兼容性。默认情况下,文件对象都以二进制模式打开。

如果给出, ? startupinfo ?将是一个将被传递给底层的?CreateProcess?函数的? STARTUPINFO ?对象。

creationflags ,如果给出,可以是一个或多个以下标志之一:

CREATE_NEW_CONSOLE

CREATE_NEW_PROCESS_GROUP

ABOVE_NORMAL_PRIORITY_CLASS

BELOW_NORMAL_PRIORITY_CLASS

HIGH_PRIORITY_CLASS

IDLE_PRIORITY_CLASS

NORMAL_PRIORITY_CLASS

REALTIME_PRIORITY_CLASS

CREATE_NO_WINDOW

DETACHED_PROCESS

CREATE_DEFAULT_ERROR_MODE

CREATE_BREAKAWAY_FROM_JOB

Popen 对象支持通过? with ?语句作为上下文管理器,在退出时关闭文件描述符并等待进程:。

在 3.6 版更改:?现在,如果 Popen 析构时子进程仍然在运行,则析构器会发送一个? ResourceWarning ?警告。

在 3.8 版更改:?在某些情况下 Popen 可以使用? os.posix_spawn() ?以获得更好的性能。在适用于 Linux 的 Windows 子系统和 QEMU 用户模拟器上,使用? os.posix_spawn() ?的 Popen 构造器不再会因找不到程序等错误而引发异常,而是上下级进程失败并返回一个非零的? returncode 。

异常

在子进程中抛出的异常,在新的进程开始执行前,将会被再次在父进程中抛出。

最常见的被抛出异常是? OSError 。例如,当尝试执行一个不存在的文件时就会发生。应用程序需要为? OSError ?异常做好保护。

如果? Popen ?调用时有无效的参数,则一个? ValueError ?将被抛出 。

check_all()?与? check_output() ?在调用的进程返回非零退出码时将 抛出? CalledProcessError 。

所有接受? timeout ?形参的函数与方法,例如? call() ?和? Popen.communicate() ?将会在进程退出前超时到期时 抛出? TimeoutExpired 。

此模块中定义的异常都继承自? SubprocessError 。

(责任编辑:IT教学网)

更多