popen函数的用法,system函数和popen函数
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 。