linux中常用的编程小技巧

在代码中执行shell命令

1.system(“shell”);

在代码中执行shell命令可以通过“stdlib.h”中的system来执行。代码示例如下:

1
2
3
4
5
6
7
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
int main(void){
int res = system("ls -l /home");
return 0;
}
            细心的朋友应该发现了,*system函数是有返回值*的。那么他的返回值是用来干什么的呢?

            system函数对返回值的处理,涉及3个阶段:

            为了更好的理解system()函数返回值,需要了解其执行过程,实际上system()函数执行了三步操作:

            1.fork一个子进程;失败返回-1.

            2.在子进程中调用exec函数去执行command;

            3.在父进程中调用wait去等待子进程结束。

            对于fork失败,system()函数返回-1。

            如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。

            (注意,command顺利执行不代表执行成功,比如command:"rm debuglog.txt",不管文件存不存在该command都顺利执行了)

            如果exec执行失败,也即command没有顺利执行,比如被信号中断,或者command命令根本不存在,system()函数返回127.

            如果command为NULL,则system()函数返回非0值,一般为1.

            备注1:

            只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。

            比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。即使shell脚本不存在或没有执行权限,也都算正常执行结束。

            如果shell脚本执行过程中被强制kill掉等情况则算异常结束。

            *system*源码
                                                                                                                                                                                                    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

```c
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

int system(const char *cmdstring) {
pid_t pid;
int status;
int if (cmdstring == NULL) { return (1); }

if ((pid = fork()) < 0) {
status = -1;
} else if (pid = 0) {
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);

-exit(127); //子进程正常执行则不会执行此语句

} else {
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTER) {
status = -1;

break;
}
}
}
return status;
}

2.execl函数

1
2
3
4
5
6
7
8
9
Linux下头文件
#include<unistd.h>
函数定义 int execl(const char *path, const char *arg, ...);
函数说明:execl() 其中后缀
"l"代表list也就是参数列表的意思,第一参数path字符指针所指向要执行的文件路径, 接下来的参数代表执行该文件时传递的参数列表:argv[0],
argv[1]... 最后一个参数须用空指针NULL作结束。

函数返回值: 成功则不返回值, 失败返回
- 1, 失败原因存于errno中,可通过perror() 打印

execl函数特点 : 当进程调用一种exec函数时,该 进程完全由新程序代换 **,而 **新程序则从其main函数开始执行 **。因为调用exec并不创建新进程 **,所以前后的进程ID并未改变。 **exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段 **用另一个新程序替换了当前进程的正文、数据、堆和栈段. 当前进程的正文都被替换了,那么execl后的语句,即便execl退出了,都不会被执行。

函数说明:execlp()

​ 会从PATH 环境变量所指的目录中 查找符合参数file的文件名,找到后便执行该文件.然后 将第二个以后的参数当做该文件的argv[0]、argv[1 **最后一个参数必须用空指针(NULL) 作结束 **如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功进程自己的执行代码就会变成加载程序的代码,execlp() 后边的代码也就不会执行了.

返回值:如果执行成功则函数不会返回,执行失败则直接返回 - 1,失败原因存于errno 中。

示例:

                                                                                                                                                                                                                                                                                                                        
1
2
3
4
5
execlp(“ls”,”ls”,”*-* al”,”*/* etc */* passwd”, (*char* ***)0);

execlp("qvfb", "qvfb", "-width", "800", "-height", "600", "-depth", "16", NULL);

*//路径,命令名,参数。。。。,null。*