目录
[2、Python 脚本 (python.py)](#2、Python 脚本 (python.py))
[3、C++ 程序 (test.cc)](#3、C++ 程序 (test.cc))
[C 程序 (proc.c)](#C 程序 (proc.c))
当你掌握了C语言、C++或Java等高级语言时,你可能仅了解函数间的相互调用。但随着深入学习进程相关知识,你会发现程序之间同样可以实现相互调用。在学习新内容之前,我们先探讨函数与进程的相似性。exec/exit 机制类似于函数调用中的 call/return 模式。
以C语言为例,你应该掌握以下核心概念:
- 一个C程序由多个函数构成,函数之间可以相互调用并传递参数
- 被调函数执行特定操作后会返回结果值
- 每个函数都拥有独立的局部变量空间
- 函数间通过call/return机制进行通信
这种基于参数传递和返回值、在保持数据私密性的函数间进行通信的模式,构成了结构化程序设计的基础。Linux系统将这种程序内部的设计理念进一步扩展到了程序间的交互中,如下图所示:

通过fork
系统调用,父进程可以创建子进程。随后使用exec
系列函数,子进程能够加载并执行其他程序,替换原有代码和数据,子进程通过exit(n)返回状态值,父进程则通过wait(&ret)系统调用获取子进程的退出状态。这种机制实现了程序间的调用与切换。
cpp
pid_t id = fork();
if (id == 0){
execvp(myargv[0], myargv);
exit(1);
}
程序执行完毕后,会通过exit(n)
返回一个状态值。调用进程可使用wait
或waitpid
函数来获取该返回值。
cpp
wait(&status);
waitpid(id, &status, 0);
程序间调用的优势之一
不同编程语言各有其特长,在实际开发中,我们常需要组合使用多种语言。通过程序间的相互调用,就能实现不同语言的无缝衔接。
例如,C程序可以通过exec系列函数来调用Shell脚本、Python或C++等语言编写的程序。
1、Shell脚本
这是一个简单的 Bash 脚本文件 test.sh
,内容如下:
bash
#!/bin/bash
i=0
while [ $i -le 10 ]
do
echo "hello shell:$i"
let i++
done
脚本功能说明:
-
#!/bin/bash
:指定脚本使用 Bash 解释器执行。 -
i=0
:初始化变量i
的值为 0。 -
while [ $i -le 10 ]
:当i
的值小于或等于 10 时,循环继续执行。 -
echo "hello shell:$i"
:打印字符串hello shell:
并附带当前i
的值。 -
let i++
:每次循环结束后,将i
的值加 1。 -
done
:标记循环结束。
执行效果
运行此脚本会输出 11 行内容(从 i=0
到 i=10
),每行格式为 hello shell:
后跟当前循环计数器的值。
使用方法:
-
将脚本保存为
test.sh
。 -
赋予执行权限:
chmod +x test.sh
。 -
运行脚本:
./test.sh
。
输出示例:

2、Python 脚本 (python.py
)
bash
#!/usr/bin/python
print("hello python!")
功能说明:
-
#!/usr/bin/python
:指定脚本使用 Python 解释器执行。 -
print("hello python!")
:打印字符串hello python!
。
使用方法:
-
将脚本保存为
python.py
。 -
赋予执行权限(可选):
chmod +x python.py
。 -
运行脚本:
-
直接执行:
./test.py
(需确保 Python 路径正确)。 -
或通过 Python 解释器运行:
python python.py
。
-
输出:

3、C++ 程序 (test.cc
)
cpp
#include <iostream>
using namespace std;
int main()
{
cout << "hello C++" << endl;
return 0;
}
功能说明:
-
#include <iostream>
:引入标准输入输出库。 -
using namespace std
:使用标准命名空间,避免重复写std::
。 -
cout << "hello C++" << endl
:打印字符串hello C++
并换行。 -
return 0
:表示程序正常退出。
编译与运行:
-
将代码保存为
test.cc
。 -
编译(需安装 g++):
bashg++ test.cc -o test
-
运行生成的可执行文件:
bash./test
输出:

4、三者的对比总结
特性 | Bash 脚本 | Python 脚本 | C++ 程序 |
---|---|---|---|
文件扩展名 | .sh |
.py |
.cc 或 .cpp |
执行方式 | 解释执行(直接或通过 Bash) | 解释执行(直接或通过 Python) | 需编译后运行二进制文件 |
语法复杂度 | 简单(面向命令) | 简洁(高级抽象) | 复杂(需管理内存、类型等) |
性能 | 低(依赖系统 Shell) | 中等(解释器开销) | 高(直接编译为机器码) |
典型用途 | 系统管理、自动化任务 | 快速开发、脚本工具 | 高性能应用、底层开发 |
依赖 | 需 Bash 环境 | 需 Python 环境 | 需编译器(如 g++) |
补充说明
-
Bash 脚本 (
test.sh
):适用于 Linux/Unix 系统自动化任务,无需编译,直接解释执行。 -
Python 脚本 (
test.py
):跨平台,适合快速开发,解释执行,依赖 Python 环境。 -
C++ 程序 (
test.cc
) :高性能场景,需编译(如g++ test.cc -o test
),生成可执行文件后运行。
程序替换
我们使用以下C程序,便可以分别调用以上三个程序:
C 程序 (proc.c
)
cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t id = fork();
if (id == 0) {
// 子进程
execl("./test.sh", "test.sh", NULL); // 调用 Bash 脚本
// execl("./python.py", "python.py", NULL); // 调用 Python 脚本
// execl("./test", "test", NULL); // 调用 C++ 程序
exit(1); // 若 execl 失败则退出
}
// 父进程等待子进程结束
int status = 0;
pid_t ret = waitpid(id, &status, 0);
if (ret > 0) {
printf("exit code: %d\n", WEXITSTATUS(status));
}
return 0;
}
功能说明
-
多进程控制:
-
使用
fork()
创建子进程,子进程通过execl()
调用外部程序。 -
父进程通过
waitpid()
等待子进程结束,并获取其退出状态码。
-
-
调用方式:
-
Bash 脚本 :
execl("./test.sh", "test.sh", NULL)
-
Python 脚本 :
execl("./python.py", "python.py", NULL)
(需取消注释) -
C++ 程序 :
execl("./test", "test", NULL)
(需先编译test.cc
生成test
)
-
-
注意事项:
-
被调用的程序(如
test.sh
、python
.py
、test
)需具有可执行权限。 -
若
execl()
调用失败,子进程会执行exit(1)
,父进程捕获的退出码为1
。
-
编译与运行
-
编译 C 程序:
bashgcc proc.c -o proc
-
运行程序:
bash./proc
-
输出示例:
调用shell脚本运行结果:

调用python运行结果:

调用C++运行结果:

对比表格
调用目标 | 语言 | 需提前准备 | C 中调用方法 |
---|---|---|---|
test.sh |
Bash | 赋予执行权限 (chmod +x ) |
execl("./test.sh", "test.sh", NULL) |
test.py |
Python | 确保 Python 环境可用 | execl("./ python .py", " python .py", NULL) |
test |
C++ | 编译生成可执行文件 (g++ ) |
execl("./test", "test", NULL) |
总结
-
用途:该 C 程序通过进程管理实现了对多种语言脚本/程序的灵活调用,适用于需要混合编程的场景(如用 C 控制任务流程,调用其他语言模块)。
-
扩展性 :可通过修改
execl()
参数调用其他外部程序(如 Perl、Java 等)。