linux:进程相关知识(三)

命令行参数

C程序的main函数原型

int main(int argc, char *argv[]);

参数

操作系统将命令行参数传递给main函数

  • argc,命令行参数的个数
  • argv,命令行参数数组

例子

cp /etc/passwd passwd.bak
argc = 3
argv = {"cp", "/etc/passwd", "passwd.bak"}

命令名也被当作是命令参数,所以argc != 2

execl

原型

#include <unistd.h>

int execl(const char *path, const char *arg, ...);

功能

  • 将当前进程的地址空间的内容全部清空
  • 将path指定的可执行程序的代码和数据装入到当前进程的地址空间
    参数
  • 该函数的参数个数可变
  • 最后一个参数必须是NULL
  • 第一个参数path指定被装入程序的路径
    • 可以是命令的绝对路径
    • 可以是命令的相对路径

返回值

  • 装入失败后,返回值为-1
  • 装入成功后,从被装入程序的main函数开始执行

execlp

原型

#include <unistd.h>

int execlp(const char *file, const char *arg, ...);

功能

与execl相同

execl和execlp的区别

在execl中,第一个参数指定可执行程序的路径
该路径可以是

  • 绝对路径
  • 相对于当前工作目录的相对路径
    在execlp中,第一个参数指定可执行程序的路径
    该路径可以是
  • 绝对路径
  • 相对于当前工作目录的相对路径
  • PATH环境变量指定目录下的相对路径

例子

#include <stdio.h>
#include <unistd.h> 

int main()
{
    puts("before exec");
    int error = execlp("echo", "echo", "a", "b", "c", NULL);  
    if (error < 0)
        perror("execl");
    puts("after exec");
    return 0;
}

output:

$ cc execlp.c
$ ./a.out
before exec
a b c
$ _

execv

原型

#include <unistd.h>
    
int execv(const char *path, const char *argv[]);

功能

与execl相同

参数

  • argv指定传递给程序的参数,argv数组的最后一项必须是NULL指针

execl和execv的区别

execl,函数名execl末尾的l表示list,参数以列表的形式传递给可执行程序

execl("/bin/echo", "echo", "a", "b", "c", NULL);

execv,函数名execv末尾的v表示vector,参数以数组的形式传递给可执行程序

char *argv[] = {"echo", "a", "b", "c", NULL};
execv("/bin/echo", argv);

execvp

同上

例子

#include <stdio.h>
#include <unistd.h> 

int main()
{
    puts("before exec"); 
    char *argv[] = {"echo", "a", "b", "c", NULL};
    int error = execvp("echo", argv);  
    if (error < 0)
        perror("execv");
    puts("after exec");
    return 0;
}

exit

原型

#include <stdlib.h>

void exit(int status);

功能

  • 正常退出当前进程
    将status & 0xFF作为退出码返回给父进程
  • 预定义常量
    EXIT_SUCCESS,为0的数值,表示程序正常退出
    EXIT_FAILURE,为非0的数值,表示程序执行过程发生了错误,异常退出
  • 在linux shell中,可以通过特殊的环境变量$?获得程序的退出码

atexit

原型

#include <stdlib.h>

int atexit(void (*function)(void));

功能

  • 注册一个回调函数function,进程正常结束时,function会被调用
    如果注册多个回调函数,进程结束时,以与注册相反的顺序调用回调函数

例子

#include <stdio.h>
#include <stdlib.h>

void f1()
{
    puts("f1");
}
 
void f2()
{
    puts("f2");
}
 
void f3()
{
    puts("f3");
}

int main()
{ 
    atexit(f1);
    atexit(f2);
    atexit(f3);
    puts("main");
    return 0;
}

输出:

$ cc atexit.c
$ ./a.out
main
f3
f2
f1
$ _

wait

原型

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);

功能

  • 等待子进程结束

参数

  • status,如果status不为NULL,子进程的退出码保存在status指向的变量中

退出码

  • 进程可能由于不同的原因退出
  • 主动调用exit正常退出
  • 接受信号后退出
  • 查询退出原因的宏
名称功能
WIFEXITED(status)如果进程通过调用exit正常退出,则返回真
WEXITSTATUS(status)如果进程通过调用exit正常退出,返回进程的退出码
WIFSIGNALED(status)如果进程接受信号后退出,则返回真
WTERMSIG(status)如果进程接受信号后退出,返回导致进程退出的信号

例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child()
{
    exit(123);
}

int main()
{
    int pid;
    pid = fork();
    if (pid == 0)
        child(); 

    int status;
    wait(&status);
    if (WIFEXITED(status)) {
        printf("WIFEXITED = true\n"); 
        printf("WEXITSTATUS = %d\n",  WEXITSTATUS(status));
    }
    return 0;
}
  • 父进程调用wait,等待子进程结束
  • 将变量status的地址传递给wait
  • 用于接受子进程的退出码
$ cc wait2.c
$ ./a.out
WIFEXITED = true
WEXITSTATUS = 123
$ _
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值