linux shell调用shell python调用shell命令

大家好,感谢邀请,今天来为大家分享一下linux shell调用shell的问题,以及和python调用shell命令的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

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中。

如何在java程序中调用linux命令或者shell脚本

这里不得不提到java的process类了。

process这个类是一个抽象类,封装了一个进程(你在调用linux的命令或者shell脚本就是为了执行一个在linux下执行的程序,所以应该使用process类)。

process类提供了执行从进程输入,执行输出到进程,等待进程完成,检查进程的推出状态,以及shut down掉进程。

至于详细的process类的介绍放在以后介绍。

另外还要注意一个类:Runtime类,Runtime类是一个与JVM运行时环境有关的类,这个类是Singleton的。

这里用到的Runtime.getRuntime()方法是取得当前JVM的运行环境,也是java中唯一可以得到运行环境的方法。(另外,Runtime的大部分方法都是实例方法,也就是说每次运行调用的时候都需要调用到getRuntime方法)

下面说说Runtime的exec()方法,这里要注意的有一点,就是public Process exec(String [] cmdArray, String [] envp);这个方法中cmdArray是一个执行的命令和参数的字符串数组,数组的第一个元素是要执行的命令往后依次都是命令的参数,envp感觉应该和C中的execve中的环境变量是一样的,envp中使用的是name=value的方式。

下面说一下,如何使用process来调用shell脚本

例如,我需要在linux下实行linux命令:sh test.sh,下面就是执行test.sh命令的方法:

这个var参数就是日期这个201102包的名字。

String shpath="/test/test.sh";//程序路径

Process process=null;

String command1=“chmod 777”+ shpath;

process= Runtime.getRuntime().exec(command1);

process.waitFor();

String var="201102";//参数

String command2=“/bin/sh”+ shpath+””+ var;

Runtime.getRuntime().exec(command2).waitFor();

注意:

1

我为什么要使用 chmod 777命令呢?在有的机器上面,可能没有设置权限问题。这是你在linux下面执行shell脚本需要注意的问题。没有的话,就需要添加权限,就用chmod 777,否则在执行到Runtime.getRuntime().exec的时侯会出现Permission denied错误。

2

waitFor()这个也是必不可缺的,如果你需要执行多行命令的话,把waitFor()这个加上。

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()函数来让子进程退出!

阅读剩余
THE END