linux程序中调用命令 linux程序调用shell

java程序里如何调用linux命令?Java可以通过Runtime调用Linux命令linux程序中调用命令 , 形式如下linux程序中调用命令:
Runtime.getRuntime().exec(command)
但是这样执行时没有任何输出linux程序中调用命令,因为调用Runtime.exec方法将产生一个本地linux程序中调用命令的进程 , 并返回一个Process子类的实例(注意:Runtime.getRuntime().exec(command)返回的是一个Process类的实例)该实例可用于控制进程或取得进程的相关信息 。
由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过Process.getOutputStream(),Process.getInputStream(),Process.getErrorStream()方法重定向给它的父进程linux程序中调用命令了 。
用户需要用这些stream来向子进程输入数据或获取子进程的输出,下面的代码可以取到linux命令的执行结果:
try{
String[]cmd=newString[]{”/bin/sh”,“-c”,”ls“};
Processps=Runtime.getRuntime().exec(cmd);
BufferedReaderbr=newBufferedReader(newInputStreamReader(ps.getInputStream()));
StringBuffersb=newStringBuffer();
Stringline;
while((line=br.readLine())!=null){
sb.append(line).append(”\n”);
}
Stringresult=sb.toString();
System.out.println(result);
}catch(Exceptione){
e.printStackTrace();
}
Linux中c如何调用终端命令C语言有一个system函数(在stdlib.h头中 , C则为cstdlib头),可以用来调用终端命令 。原型如下linux程序中调用命令:
int system(const char *cmdline /* 命令字符串 */
);
例如,Linux系统中,调用system("ls -la");将输出当前目录下linux程序中调用命令的所有文件详细信息 。
Windows系统linux程序中调用命令的“终端”(命令提示符)和Linux中linux程序中调用命令的终端不一样,Windows系统中要实现同样功能,需要调用system("dir /a");
对system函数的详细解释见 。
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;"#includestdlib.h
intmain()
{
system("bash /home/book/shell/test.sh"); /* chmodx 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文件:
#includestdio.h
intmain()
{
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()函数来让子进程退出!
如何在自己写的 Linux C 程序中以一种优雅的方式调用一些命令Linux C编程启动另一个可执行文件或调用命令用system函数最理想了,这个函数原理是在你编写的那个程序的内部启动另一个程序或命令 , 从而创建一个新进程,并等待这个进程执行完毕退出 。如果正常执行 , system函数将返回被执行程序或命令的退出码;如果无法运行这个程序或命令 , 将返回错误代码127;如果是其他错误,返回-1 。这个函数的原型是:
#include stdlib.h
int system(const char *string);
参数string是将要执行的程序或命令的命令字符串 。
还有一种执行外部程序的方法是exec系列函数,但这个系列的函数都是将当前进程的替换成新进程,也就是说新进程启动后原来的进程就不存在了,exec系列函数后面的那些代码就不会再执行了 。所以我一般是用system函数调用Linux命令 。
linux系统下 程序中运行操作系统命令,详细解释S中设置的启动设备(通常是硬盘)启动 ,
接着启动设备上安装的引导程序lilo或grub开始引导Linux,Linux首先进行内核的引导,
接下来执行init程序,init程序调用了rc.sysinit和rc等程序,rc.sysinit和rc当完成系
统初始化和运行服务的任务后,返回init;init启动了mingetty后,打开了终端供用户登
录系统,用户登录成功后进入了Shell,这样就完成了从开机到登录的整个启动过程 。
加载内核
LILO启动之后,如果你选择了Linux作为准备引导的操作系统,第一个被加载的东西就是内核 。请记住此时的计算机内存中还不存在任何操作系统,PC(因为它们天然的设计缺陷)也还没有办法存取机器上全部的内存 。因此 , 内核就必须完整地加载到可用RAM的第一个兆字节之内 。为了实现这个目的,内核是被压缩了的 。这个文件的头部包含着必要的代码 , 先设置CPU进入安全模式(以此解除内存限制) , 再对内核的剩余部分进行解压缩 。
执行内核
内核在内存中解压缩之后,就可以开始运行了 。此时的内核只知道它本身内建的各种功能 , 也就是说被编译为模块的内核部分还不能使用 。最基本的是,内核必须有足够的代码设置自己的虚拟内存子系统和根文件系统(通常就是ext2文件系统) 。一旦内核启动运行,对硬件的检测就会决定需要对哪些设备驱动程序进行初始化 。从这里开始 , 内核就能够挂装根文件系统(这个过程类似于Windows识别并存取C盘的过程) 。内核挂装了根文件系统之后,将启动并运行一个叫做 init的程序 。
注意:在这里我们故意略去了Linux内核启动的许多细节,这些细节只有内核开发人员才感兴趣 。如果你好奇的话,可以访问http://地址处的 “Kernel Hackers Guide” 。
init进程
init进程是非内核进程中第一个被启动运行的,因此它的进程编号PID的值总是1 。init读它的配置文件/etc/inittab,决定需要启动的运行级别(Runlevel) 。从根本上说 , 运行级别规定了整个系统的行为,每个级别(分别由0到6的整数表示)满足特定的目的 。如果定义了 initdefault级别,这个值就直接被选中,否则需要由用户输入一个代表运行级别的数值 。
输入代表运行级别的数字之后 , init根据/etc/inittab文件中的定义执行一个命令脚本程序 。缺省的运行级别取决于安装阶段对登录程序的选择:是使用基于文本的,还是使用基于X-Window的登录程序 。
rc命令脚本程序
我们已经知道,当运行级别发生改变时,将由/etc/inittab文件定义需要运行哪一个命令脚本程序 。这些命令脚本程序负责启动或者停止该运行级别特定的各种服务 。由于需要管理的服务数量很多 , 因此需要使用rc命令脚本程序 。其中,最主要的一个是/etc/rc.d/rc,它负责为每一个运行级别按照正确的顺序调用相应的命令脚本程序 。我们可以想象,这样一个命令脚本程序很容易变得难以控制!为了防止这类事件的发生,需要使用精心设计的方案 。
对每一个运行级别来说 , 在/etc/rc.d子目录中都有一个对应的下级目录 。这些运行级别的下级子目录的命名方法是rcX.d,其中的X就是代表运行级别的数字 。比如说,运行级别3的全部命令脚本程序都保存在/etc/rc.d/rc3.d子目录中 。
在各个运行级别的子目录中 , 都建立有到/etc/rc.d/init.d子目录中命令脚本程序的符号链接,但是,这些符号链接并不使用命令脚本程序在 /etc/rc.d/init.d子目录中原来的名字 。如果命令脚本程序是用来启动一个服务的 , 其符号链接的名字就以字母S打头;如果命令脚本程序是用来关闭一个服务的,其符号链接的名字就以字母K打头 。
许多情况下,这些命令脚本程序的执行顺序都很重要 。如果没有先配置网络接口,就没有办法使用DNS服务解析主机名!为了安排它们的执行顺序,在字母S 或者K的后面紧跟着一个两位数字,数值小的在数值大的前面执行 。比如:/etc/rc.d/rc3.d/S50inet就会在 /etc/rc.d/rc3.d/S55named之前执行(S50inet配置网络设置,S55named启动DNS服务器) 。
存放在/etc/rc.d/init.d子目录中的、被符号链接上的命令脚本程序是真正的实干家,是它们完成了启动或者停止各种服务的操作过程 。当 /etc/rc.d/rc运行通过每个特定的运行级别子目录的时候,它会根据数字的顺序依次调用各个命令脚本程序执行 。它先运行以字母K打头的命令脚本程序,然后再运行以字母S打头的命令脚本程序 。对以字母K打头的命令脚本程序来说,会传递Stop参数;类似地对以字母S打头的命令脚本程序来说,会传递 Start参数 。
编写自己的rc命令脚本
在维护Linux系统运转的日子里 , 肯定会遇到需要系统管理员对开机或者关机命令脚本进行修改的情况 。有两种方法可以用来实现修改的目的:
● 如果所做的修改只在引导开机的时候起作用,并且改动不大的话,可以考虑简单地编辑一下/etc/rc.d/rc.local脚本 。这个命令脚本程序是在引导过程的最后一步被执行的 。
● 如果所做的修改比较细致,或者还要求关闭进程使之明确地停止运行,则需要在/etc/rc.d/init.d子目录中添加一个命令脚本程序 。这个命令脚本程序必须可以接受Start和Stop参数并完成相应的操作 。
第一种方法,编辑/etc/rc.d/rc.local脚本,当然是两种方法中比较简单的 。如果想在这个命令脚本程序中添加内容,只需要使用喜欢的编辑器程序打开它,再把打算执行的命令附加到文件的末尾就可以了 。这对一两行的修改来说的确很便利 。
如果确实需要使用一个命令脚本程序,这时必须选择第二个方法 。编写一个rc命令脚本程序的过程并不像想象中那么困难 。我们下面就给出一个例子,看看它是怎样实现的(顺便说一句 , 你可以把我们的例子当作范本,按照自己的需要进行修改和添加) 。
假设你打算每隔60分钟调用一个特殊的程序来弹出一条消息,提醒自己需要从键盘前面离开休息一会儿,命令脚本程序将包括下面几个部分:
● 关于这个命令脚本程序功能的说明(这样就不会在一年之后忘记它);
● 在试图运行它之前验证这个命令脚本程序确实存在;
● 接受start和stop参数并执行要求的动作 。
参数给定后 , 我们就可以编写命令的脚本程序 。这个程序很简单,大家可以自己编写一下 , 我在这里就不给出了 。
编写好新的命令脚本程序之后,再从相关的运行级别子目录中加上必要的符号链接,来控制这个命令脚本程序的启动或者停止 。在我的印象中 , 只想让它在运行级别3或者运行级别5中启动,原因是我认为只有这两个运行级别才是日常工作的地方 。最后,希望这个命令脚本程序在进入运行级别6(重启动)的时候被关闭 。
激活或者禁止服务项目
有的时候会发现,在引导的时候并不需要某个特定的服务被启动 。如果你正在考虑使用Linux替换Windows NT的文件和打印服务器,就更是如此 。
我们已经知道,在特定的运行级别子目录中给符号链接改个名称,就可以让该服务不被启动,如把其名称的第一个字母由S改为K 。一旦熟练掌握了命令行和符号链接,就会发现这是激活或者禁止服务的最快办法 。
在学习这个改名方法的时候,可能会觉得图形化的操作界面ksysv比较容易掌握 。虽然它原来是设计使用在KDE环境里的 , 但在 Red Hat Linux 7.2下缺省安装的GNOME环境里也运行得很好 。如果想启动它,只需简单地打开一个xterm窗口,并输入ksysv命令就可以了 。屏幕上会出现一个窗口,其中列出了能够修改的全部参数,需要时还包括在线帮助 。
警告:如果是在一个现实中的系统上学习本文的知识,要多多运用常识 。当试着对启动脚本程序进行修改的时候 , 要记住所做的修改可能会造成你的系统不能正常工作,而且无法采用重启动的方法恢复 。不要在正常运转的系统上实验新的设置,对你准备修改的文件要全部进行备份 。最重要的是,在手边要准备一张引导盘以防不测
另外,虚机团上产品团购,超级便宜
linux下如何用c语言调用shell命令在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脚本tsh.sh,内容为
#!/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程序popentest.c内容如下:
#include
main
{
【linux程序中调用命令 linux程序调用shell】file
*
fp;
charbuffer[80];
fp=popen(“~/myprogram/test.sh”,”r”);
fgets(buffer,sizeof(buffer),fp);
printf(“%s”,buffer);
pclose(fp);
}
关于linux程序中调用命令和linux程序调用shell的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息 , 记得收藏关注本站 。

    推荐阅读