linux c 调用shell,linux打开软件命令
大家好,今天小编来为大家解答以下的问题,关于linux c 调用shell,linux打开软件命令这个很多人还不知道,现在让我们一起来看看吧!
linux下如何用c语言调用shell命令
参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。返回值:若成功则返回文件指针,否则返回NULL,错误原因存于errno中。注意:在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。例:C程序popentest.c内容如下:#include<stdio.h> main(){ FILE* fp; charbuffer[80]; fp=popen(“~/myprogram/test.sh”,”r”); fgets(buffer,sizeof(buffer),fp); printf(“%s”,buffer); pclose(fp);}执行结果如下: xiakeyou@ubuntu:~/myprogram$ vim popentest.c xiakeyou@ubuntu:~/myprogram$ gcc popentest.c-o popentest xiakeyou@ubuntu:~/myprogram$./popentest/home/d/e/xiakeyou xiakeyou@ubuntu:~/myprogram$只是偶能力可能有点有限,没有太看懂。直接用system()倒是脚本可是执行,只是返回值却是一塌糊涂,试了多次也没有找到什么规律。不免又看了一下上面的那篇博文,得到一些启发,可以这样来实现:先将脚本的返回值利用 echo> XXXXX输出到一个本地文件中当需要这个返回值是,可是通过C语言的文件操作函数来直接从文件中读取后来一想,这应该就是上文中POPEN的实现方法! C程序调用shell脚本共有三种法子:system()、popen()、exec系列函数 system()不用你自己去产生进程,它已经封装了,直接加入自己的命令exec需要你自己 fork进程,然后exec自己的命令 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命令以其简略高效的作用得到很很广泛的利用,下面是一个例子例:在~/test/目录下有shell脚本test.sh,内容为#!bin/bash#test.sh echo hello在同层目录下新建一个c文件system_test.c,内容为:#include<stdlib.h> int main(){ system("~/test/test.sh");}履行效果如下: [root@localhost test]$gcc system_test.c-o system_test [root@localhost test]$./system_test hello [root@localhost test]$ 2)popen(char*command,char*type) popen()会调用fork()产生子历程,然后从子历程中调用/bin/sh-c来履行参数command的指令。参数type可应用“r”代表读取,“w”代表写入。遵循此type值,popen()会建立管道连到子历程的标准输出设备或标准输入设备,然后返回一个文件指针。随后历程便可利用此文件指针来读取子历程的输出设备或是写入到子历程的标准输入设备中。此外,所有应用文件指针(FILE*)操作的函数也都可以应用,除了fclose()以外。返回值:若成功则返回文件指针,否则返回NULL,差错原因存于errno中。
linux系统调用 shell命令 c库函数怎么区分
首先,命令应该是好和其他两个区分开来的了,因为命令都是可以直接敲在shell上面回车执行的,而系统调用和库函数都不行;
其次,Linux系统调用和C库函数都是函数的形式,即都是“func(args)”的形式,但系统调用是
由系统内核对外提供的服务接口;C库函数和你自己写的普通的函数没有本质的区别,只是在C标准库中而已,Linux上面glibc就是C函数库。从表面上看两者不太好区分,不过,你可以从它们需要包含的头文件来区分,C库函数像printf在
中,std就是标准(standard)的缩写形式,因此在
中的函数,基本都是C库函数;像
ssize_t
read(int
fd,
void
*buf,
size_t
count);这样很多的系统调用是包含在
中的,unistd意思是UNIX
Standard,从这个意义就可以区分了。
希望对你有所帮助,如还有问题,可随时联系我:-)
linux下怎样用c语言调用shell命令
C程序调用shell脚本共同拥有三种法子:system()、popen()、exec系列数call_exec1.c,
system()不用你自己去产生进程。它已经封装了,直接增加自己的命令
exec须要你自己 fork进程,然后exec自己的命令
popen()也能够实现运行你的命令,比system开销小
方法一、system()的使用。我直接上代码吧
int system(const char*command);
我在/home/book/shell新建一个test.sh文件例如以下:
<span style="font-size:18px;"><span style="font-size:18px;">#!bin/bash
echo$HOME
echo"the is test!"</span></span>
test.c文件例如以下:
<span style="font-size:18px;"><span style="font-size:18px;">#include<stdlib.h>
int main()
{
system("bash/home/book/shell/test.sh");/* chmod+x test.sh,路径前面要加上bash*/
return 0;
}</span></span>
运行例如以下命令来编译:
<span style="font-size:18px;">gcc test.c-o test
</span>
测试命令:
<span style="font-size:18px;">./test</span>
结果例如以下:
<span style="font-size:18px;">/root
the is test!</span>
方法二:popen()会调用fork()产生子历程,然后从子历程中调用/bin/sh-c来履行参数command的指令。参数type可应用“r”代表读取。“w”代表写入。遵循此type值。popen()会建立管道连到子历程的标准输出设备或标准输入设备,然后返回一个文件指针。
随后历程便可利用此文件指针来读取子历程的输出设备或是写入到子历程的标准输入设备中。此外,全部应用文件指针(FILE*)操作的函数也都能够应用,除了fclose()以外。
返回值:若成功则返回文件指针,否则返回NULL,差错原因存于errno中。注意:在编写具SUID/SGID权限的程序时请尽量避免应用 popen()。popen()会继承环境变量。通过环境变量可能会造成系统安全的问题
FILE*popen(const char*command, const char*type);
int pclose(FILE*stream);
其它不用改变我们直接改动test.c文件:
#include<stdio.h>
int main()
{
char buffer[80];
FILE*fp=popen("bash/home/book/shell/test.sh","r");
fgets(buffer,sizeof(buffer),fp);
printf("%s",buffer);
pclose(fp);
return 0;
}
方法三:exec函数簇(我不太懂,copy别人的。也没有验证。习惯方法一)
须要注意的是exec并非1个函数,事实上它仅仅是一组函数的统称,它包含以下6个函数:
#include<unistd.h>
int execl(const char*path, const char*arg,...);
int execlp(const char*file, const char*arg,...);
int execle(const char*path, const char*arg,..., char*const envp[]);
int execv(const char*path, char*const argv[]);
int execvp(const char*file, char*const argv[]);
int execve(const char*path, char*const argv[], char*const envp[];
能够见到这6个函数名字不同,并且他们用于接受的参数也不同.
实际上他们的功能都是几乎相同的,由于要用于接受不同的参数所以要用不同的名字区分它们,毕竟c语言没有函数重载的功能嘛..
可是实际上它们的命名是有规律的:
exec[l or v][p][e]
exec函数里的参数能够分成3个部分,运行文件部分,命令参数部分,环境变量部分.
比如我要运行1个命令 ls-l/home/gateman
运行文件部分就是"/usr/bin/ls"
命令参赛部分就是"ls","-l","/home/gateman",NULL见到是以ls开头每1个空格都必须分开成2个部分,并且以NULL结尾的啊.
环境变量部分,这是1个数组,最后的元素必须是NULL比如 char* env[]={"PATH=/home/gateman","USER=lei","STATUS=testing", NULL};
好了说下命名规则:
e兴许,参数必须带环境变量部分,环境变零部分参数会成为运行exec函数期间的环境变量,比较少用
l兴许,命令参数部分必须以","相隔,最后1个命令参数必须是NULL
v兴许,命令参数部分必须是1个以NULL结尾的字符串指针数组的头部指针.比如char* pstr就是1个字符串的指针, char* pstr[]就是数组了,分别指向各个字符串.
关于Linux命令的介绍,看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html
p兴许,运行文件部分能够不带路径, exec函数会在$PATH中找
还有1个注意的是, exec函数会代替运行它的进程,也就是说,一旦exec函数运行成功,它就不会返回了,进程结束.可是假设exec函数运行失败,它会返回失败的信息,并且进程继续运行后面的代码!
通常exec会放在fork()函数的子进程部分,来替代子进程运行啦,运行成功后子程序就会消失,可是运行失败的话,必须用exit()函数来让子进程退出!