shell和c语⾔混合编程,C语⾔和Shell交互
1、system(执⾏shell命令)
相关函数fork,execve,waitpid,popen
头⽂件:stdlib.h
函数原型:int system(const char * string);
函数说明:system()会调⽤fork()产⽣⼦进程,由⼦进程来调⽤/bin/sh-c string来执⾏参数string字符串所代表的命令,此命令执⾏完后随机返回原调⽤的进程。在调⽤system()期间SIGCHLD信号会被暂时搁置,SIGNT和SIGQUIT信号则会被忽略。
返回值:如果system()在调⽤/bin/sh时失败则返回127,其他失败原因返回1。若参数string为空指针(NULL),则返回⾮零值。如果system()调⽤成功则最后会返回
执⾏shell命令后的返回值,但是此返回值也有可能为system()调⽤/bin/sh失败所返回的127,因此最好能再检查errno来确认执⾏成功。
附加说明,在编写具有SUID/SGID权限的程序时请勿使⽤system(),system()会继承环境变量,通过环境变量
可能会造成系统安全的问题。
范例:
#include
main()
{
system("ls -al /etc/passwd /etc/shadow");
}
system
int system(const char * command);
Execute system command
Invokes the command processor to execute a command.Once the command execution has terminated, the processor gives the control back to the program, returning an int value, whose interpretation is system-dependent.
The function call also be used with NULL as argument to check whether a command processor exists.
Parameters
command
C string containing the system command to be executed.
Return Value
The value returned when the argument passed is not NULL, depends on the running environment specifications. In many systems, 0 is used to indicate that the command was successfully executed and other values to indicate some sort of error.
When the argument passed is NULL, the function returns a nonzero value if the command processor is available, and zero otherwise.
Portability
The behavior and return value are platform-dependent.
Example
/* system example : DIR */
#include
#include
int main()
{
int i;
printf("Checking if processor ");
if(system(NULL)) puts("OK");
else exit(1);
printf("Executing \n");
i = system("dir");
printf("The value returned was: %d.\n", i);
return 0;
}
2、popen(建⽴管道I/O)
相关函数:pipe,mkfifo,pclose,fork,system,fopen
头⽂件:stdio.h
函数原型:FILE * popen(const char * command, const char * type);
函数说明popen()会调⽤fork()产⽣⼦进程,然后从⼦进程调⽤/bin/sh -c来执⾏参数command的命令。
参数type可使⽤"r"代表读取,"w"代表写⼊。依照此type值,popen()会建⽴管道连到⼦程序的标准输出设备或标准输⼊设备,然后返回⼀个⽂件指针。随后进程便可利⽤此⽂件指针来读取⼦进程的输出设备或是写⼊到⼦进程的标准输⼊设备中。此外,所有使⽤⽂件指针(FILE*)操作的函数也都可以使⽤,
除了fclose()以外。
返回值:若成功则返回⽂件指针,否则返回NULL,错误原因存于errno中。错误代码:EINVAL参数type不合法。
注意事项:在编写具有SUID/SGID权限的程序时请尽量避免使⽤popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。
范例:
#include
main()
{
FILE * fp;
char buffer[80];
fp = popen("cat /etc/passwd", "r");
fgets(buffer, sizeof(buffer), fp);
printf("%s", buffer);
pclose(fp);
执⾏ root:x:0 0: root:/root: /bin/bash
Linux/Unix Command: popen
Command Library
NAME
popen, pclose - process I/O
SYNOPSIS
#include
FILE * popen(const char * command, const char * type);
int pclose(FILE * stream);
DESCRIPTION
The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is
correspondingly read-only or write-only.
The command argument is a pointer to a null-terminated string containing a shell command line. This command is passed to /bin/sh using the -c flag; interpretation, if any, is performed by the shell.The mode argument is a pointer to a null-terminated string which must be either 'r' for reading or 'w' for writing.
The return value from the popen() is a normal standard I/O stream in all respects save that it must be closed with pclose() rather than fclose(). Writing to such a stream writes to the standard input of the command; the command's standard output is the same as that of the process that called popen(), unless this is altered by the command itself. Conversely, reading
from a "popened" stream reads the command's standard output, and the command's standard input is the same as that
of the process that called popen.
Note that output popen streams are fully buffered by default.
The pclose function waits for the associated process to terminate and returns the exit status of the command as returned by wait4.
RETURN VALUE
linux命令及shell编写The popen function returns NULL if the fork(2) or pipe(2) call fail, or if it cannot allocate memory.
The pclose function returns -1 if wait4 returns an error, or some other error is detected.
ERRORS
The popen function does not set errno if memory allocation fails. If the underlying fork() or pipe() fails, errno is set appropriately. If the mode argument is invalid, and this condition is detected, errno is set to EINVAL.
if pclose() cannot obtain the child status, errno is set to ECHILD.
3、使⽤vfork()新建⼦进程,然后调⽤exec函数族
#include
main()
{
char * argv[] = {"ls", "-al", "etc/passwd", (char*)};
if(vfork() == 0)
execv("/bin/ls", argv);
}
else
{
printf("This is the parent proces");
}
}
个⼈感觉第⼆种⽅式最好了。
#include int main(void){FILE * file = popen("ls", "r");int i;for(i=0; ;++i){char buffer[1024+4];fgets(buffer, 1024,
file);if(feof(file)) break;printf("%s", buffer);}printf("%d\n", i);pclose(file);return 0;}
其实,最简单的⽅式是使⽤stdin和stdout。
main.c #include int main(void) {  char buffer[1024];  scanf("%s", buffer);  printf("Hello, %s!", buffer); } gcc main.c -o hello echo Jim | ./hello | wc -l
结果是:1
system、
popen、stdin/stdout是异步,但是表现出同步的性质。
popen、stdin/out使⽤流技术,将异步的⾼校和同步的易⽤结合在了⼀起。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。