UNIX脚本、库和系统调用之间的关系

本文讨论了如何通过应用程序调用不同类型的可执行程序(如系统本身的程序、同事编写的、以及shell和Python解释器)实现简单和复杂功能。文中给出了使用vfork和execl进行功能调用的例子,以及通过系统调用来完成库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们写一个应用程序,可以调用以下对象共同合作来完成一个功能:

其他可执行程序:系统本身的可执行程序、同事写的、各种解释器(python、shell)

                             调用单个可执行程序完成简单的功能

                             调用各种解释器运行各种脚本完成复杂功能(因为脚本里可以再调用不同程序)

公用函数库

系统调用

可以总结为:简单功能(简单的程序) vs     复杂功能(脚本组合不同程序) 

                      简单函数(系统调用)    vs     复杂函数(对系统调用的封装)

1 apue里的源代码里有个例子,稍微改一下proc/echoall.c:

#include "apue.h"

int
main(int argc, char *argv[])
{
	int			i;
	char		**ptr;
	extern char	**environ;

	for (i = 0; i < argc; i++)		/* echo all command-line args */
		printf("argv[%d]: %s\n", i, argv[i]);

	//for (ptr = environ; *ptr != 0; ptr++)	/* and all env strings */
		//printf("%s\n", *ptr);

	exit(253);
}

单独调用:

root@L-R91239GL-1157:~/study/apue.3e/intro# ./echoall para1 para2
argv[0]: ./echoall
argv[1]: para1
argv[2]: para2

2 shell脚本app.sh

#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
exit 254

单独调用

root@L-R91239GL-1157:~/study/apue.3e/intro# ./app.sh para1 para2
执行的文件名:./app.sh
第一个参数为:para1
第二个参数为:para2

3 python脚本app.py

#!/usr/bin/python
import sys
print("执行的文件名: ",sys.argv[0])
print("第一个参数为: ",sys.argv[1])
print("第二个参数为: ",sys.argv[2])
exit(255)

单独调用

root@L-R91239GL-1157:~/study/apue.3e/intro# ./app.py para1 para2
执行的文件名:  ./app.py
第一个参数为:  para1
第二个参数为:  para2

测试程序app.c:

#include "apue.h"
#include <stdlib.h>
#include <sys/wait.h>


int main(void)
{
    pid_t pid1,pid2,pid3;
    int		stat1,stat2,stat3;
    
    //本程序怎么使用操作系统的服务呢?
    //外包给同事:可执行程序,或者各种解释器(shell.python)
    printf("程序:\n");
    //简单功能
    pid1 = vfork();if (pid1 == 0) execl("echoall","not ignore","para1","para2",(char *)0);
    //复杂功能
    pid2 = vfork();if (pid2 == 0) execl("app.sh","ignore...","para1","para2",(char *)0);
    pid3 = vfork();if (pid3 == 0) execl("app.py","ignore...","para1","para2",(char *)0);
    waitpid(pid1, &stat1, 0);
    waitpid(pid2, &stat2, 0);
    waitpid(pid3, &stat3, 0);
    printf("父进程等到返回值%d__%d__%d\n",WEXITSTATUS(stat1),WEXITSTATUS(stat2),WEXITSTATUS(stat3));

    //调用直接下属:库(为什么叫直接下属呢,因为用标准库更多,很少直接调用系统调用吧)
    //复杂函数
    printf("\n库\n\n");

    //调用间接下属:系统调用
    //简单函数
    write(1, "系统调用\n", strlen("系统调用\n"));
    printf("\n");

	exit(0);
}

运行结果:

程序:
argv[0]: not ignore
argv[1]: para1
argv[2]: para2
执行的文件名:app.sh
第一个参数为:para1
第二个参数为:para2
执行的文件名:  app.py
第一个参数为:  para1
第二个参数为:  para2
父进程等到返回值253__254__255

库

系统调用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值