在C语言中调用shell命令的方法实现。
C程序调用shell脚本共有两种方法 :system()、popen(),分别如下:
system()
不用自己去创建进程,系统已经封装了这一步,直接加入自己的命令即可
popen() 也可以实现执行的命令,比system
开销小
以下分别说明:
1)system(shell命令或shell脚本路径);
system()
会调用fork()产生 子历程,由子历程来调用/bin/sh-c string来履行 参数string字符串所代表的命令,此命令履行
完后随即返回原调用的历程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被漠视 。
返
回值:如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。 如果
system()调用成功 则最后会返回履行 shell命令后的返回值,但是此返回值也有可能为system()调用/bin/sh失败所返回的127,因
此最好能再反省 errno 来确认履行 成功 。
system命令以其简略
高效的作用得到很很广泛 的利用 ,下面是一个例子
例:在/tmp/testDir/目录下有shell脚本tshsh,内容为
#!/bin/sh
wget $1
echo "Done!"
2)popen(char
command,char type)
popen()
会调用fork()产生 子历程,然后从子历程中调用/bin/sh -c来履行 参数command的指令。参数type可应用
“r”代表读取,“w”代表写入。遵循此type值,popen()会建立 管道连到子历程的标准 输出设备 或标准 输入设备
,然后返回一个文件指针。随后历程便可利用 此文件指针来读取子历程的输出设备 或是写入到子历程的标准 输入设备 中。此外,所有应用 文
件指针(FILE) *** 作的函数也都可以应用 ,除了fclose()以外。
返回值:若成功
则返回文件指针,否则返回NULL,差错 原因存于errno中。注意:在编写具SUID/SGID权限的程序时请尽量避免应用
popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。
例:C程序popentestc内容如下:
#include
main
{
FILE fp;
charbuffer[80];
fp=popen(“~/myprogram/testsh”,”r”);
fgets(buffer,sizeof(buffer),fp);
printf(“%s”,buffer);
pclose(fp);
}
鸟哥是不会有这个的,可以这样想(感觉这样很麻烦,只用一对管道应该也可以,流程也能简单,控制好进程顺序就行。这个编得过):
#include <stdioh>
#include <stdlibh>
#include <stringh>
#include <fcntlh>
#include <unistdh>
#include <sys/waith>
#define CMD_LINE 1024
#define PIPE_MAX 16
#define ARG_MAX 10
typedef struct {
char arg[ARG_MAX];
char in;
char out;
} cmd_t;
extern int parse_token(char buf, cmd_t cmd[]);
extern int parse(char buf, cmd_t cmd);
extern int test_parse(cmd_t cmd[], int len);
int main(int argc, char argv[])
{
char buf[CMD_LINE];
cmd_t cmd[PIPE_MAX + 1];
int fd[PIPE_MAX][2];
int j, i;
int cmd_len, pipe_len;
pid_t pid;
while (1) {
printf("my_shell#");
fgets(buf, CMD_LINE, stdin);
buf[strlen(buf) - 1] = '\0';
cmd_len = parse_token(buf, cmd);
pipe_len = cmd_len - 1;
if (pipe_len > PIPE_MAX)
continue;
for (i = 0; i < pipe_len; ++i)
pipe(fd[i]);
for (i = 0; i < cmd_len; ++i)
if ((pid = fork()) == 0)
break;
if (pid == 0) {
if (pipe_len) {
if (i == 0) {
close(fd[i][0]);
dup2(fd[i][1], 1);
close(fd[i][1]);
for (j = 1; j < pipe_len; ++j)
close(fd[j][0]),
close(fd[j][1]);
} else if (i == pipe_len) {
close(fd[i - 1][1]);
dup2(fd[i - 1][0], 0);
close(fd[i - 1][0]);
for (j = 0; j < pipe_len - 1; ++j)
close(fd[j][0]),
close(fd[j][1]);
} else {
dup2(fd[i - 1][0], 0);
close(fd[i][0]);
dup2(fd[i][1], 1);
close(fd[i][1]);
for (j = 0; j < pipe_len; ++j) {
if ((j != i - 1)
|| (j != i))
close(fd[j][0]),
close(fd[j]
[1]);
}
}
}
if (cmd[i]in) {
int fd = open(cmd[i]in, O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);
}
if (cmd[i]out) {
int fd =
open(cmd[i]out,
O_RDWR | O_CREAT | O_TRUNC, 0644);
dup2(fd, STDOUT_FILENO);
close(fd);
}
execvp(cmd[i]arg[0], cmd[i]arg);
fprintf(stderr, "Failed exec\n");
exit(127);
}
/ parent /
for (i = 0; i < pipe_len; ++i)
close(fd[i][0]), close(fd[i][1]);
for (i = 0; i < cmd_len; ++i)
wait(NULL);
}
return 0;
}
int parse_token(char buf, cmd_t cmd[])
{
int n = 0;
#if 1
char save_p;
char p = strtok_r(buf, "|", &save_p);
while (p != NULL) {
parse(p, &cmd[n++]);
p = strtok_r(NULL, "|", &save_p);
}
#else
cmd[n]arg[0] = "ls";
cmd[n]arg[1] = "-l";
cmd[n]arg[2] = NULL;
#endif
return n;
}
int test_parse(cmd_t cmd[], int len)
{
int i;
for (i = 0; i < len; ++i) {
printf("cmd[%d]:", i);
int j = 0;
while (cmd[i]arg[j])
printf(" %s", cmd[i]arg[j++]);
if (cmd[i]in)
printf("\tin:%s", cmd[i]in);
if (cmd[i]out)
printf("\tout:%s", cmd[i]out);
printf("\n");
}
return 0;
}
int parse(char buf, cmd_t cmd)
{
int i = 0;
cmd->in = NULL;
cmd->out = NULL;
char p = strtok(buf, " ");
while (p) {
if (p == '<') {
if ((p + 1))
cmd->in = p + 1;
else
cmd->in = strtok(NULL, " ");
} else if (p == '>') {
if ((p + 1))
cmd->out = p + 1;
else
cmd->out = strtok(NULL, " ");
} else
cmd->arg[i++] = p;
p = strtok(NULL, " ");
}
cmd->arg[i] = NULL;
return 0;
}
#include<stdioh>
int main(int argc, char argv)
{
int i;
for(i=0; i<argc; i++)
printf("%s\n", argv[i]);
return 0;
}
比方这个程序叫 mainc 吧,先编译成 mainexe
gcc mainc -o mainexe
然后用命令运行
mainexe aefae 2423 asdae
程序输出:
mainexe
aefae
2423
asdae
argv 是通过命令行传送给程序的参数的字符串指针数组,argc 是参数的个数
以上就是关于关于c++调用shell命令的问题全部的内容,包括:关于c++调用shell命令的问题、如何用c语言写一个shell、c语言如何调用需传入参数的shell脚本等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)