shell命令
shell不属于内核,而是以内核之外的用户态方式运行。因此它就相当于操作系统的一层外壳,为用户提供使用操作系统的接口。
shell命令分为内置命令和外部命令,如下图,cd是外部命令,cat等都是外部命令。
当我们在命令行输入一个命令之后,会发生什么?
- 检查用户输入的命令是否是一个内部命令,如果不是检查是不是一个应用程序;
- shell在搜索路径或者环境变量中找应用程序;
- 如果不是一个外部命令并且没有查找到可执行文件,显示错误信息;- 如果成功找到,内部命令或者应用程序会被分解为系统调用传给内核,内核完成工作。
像cd,pwd这些内置命令是属于Shell的一部分,当Shell一运行起来就随Shell加载入内存,因此,当我们在命令行上输入这些命令就可以像调用函数一样直接使用,效率非常高。而如ls,cat这些外部命令却不是如此,当我们在命令行输入cat,当前的Shell会fork一个子进程,然后调用exec载入这个命令的可执行文件,比如bin/cat,(注意execve系统调用:它会把新程序加载到当前进程的内存空间内,当前的进程会被丢弃,它的堆、栈和所有的段数据都会被新进程相应的部分代替,然后会从新程序的初始化代码和 main 函数开始运行。同时,进程的 ID 将保持不变。)因此效率上稍微低了点,最后shell用wait命令等待新进程结束
shell 脚本
shell脚本原理和shell命令相同,对于外部都是使用子进程执行。
这里突发奇想shell脚本能多线程吗?查了资料是可以的:
- 使用&后台运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#/bin/bash
all_num=10
a=$(date +%H%M%S)
for num in `seq 1 ${all_num}`
do
{
sleep 1
echo ${num}
} &
done
b=$(date +%H%M%S)
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"
控制同步:
- 使用&后台运行,使用wait同步控制并发数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#/bin/bash
all_num=10
a=$(date +%H%M%S)
for num in `seq 1 ${all_num}`
do
{
sleep 1
echo ${num}
} &
done
wait
b=$(date +%H%M%S)
echo -e "startTime:\t$a"
echo -e "endTime:\t$b" - 使用xargs -P
1 | #/bin/bash |
- 使用GNU parallel
1 | #/bin/bash |