命令行的本质
在Linux程序中,最开始会有一个init进程,其他进程都是通过init进程fork出来的。比如SSHD是init fork出来的一个服务器守护进程。再比如我们所熟知的cd命令,本身也是fork出来的一个进程。
在命令中source 和sh执行有不同的含义,sh指的是fork出一个新的子进程然后去执行所传参数中的事情。source指的是再当前进程中执行命令。
exec
所做的事情是,把当前的进程替换成另一个进程。举个例子来说,在一个test.sh脚本中添加命令
exec echo "exec process"
echo "not run"
使用命令sh test.sh
运行这个脚本,执行的结果将是exec process
,下面的语句将不会执行。
命令四要素
- 环境变量(environment variable)
环境变量从本质上来说就是和进程绑定的一组键值对。fork出来的子进程一定会继承父进程的环境变量, - 可执行程序(executable)
简单来说,可执行程序就是在path路径下去命令,找到这个命令就执行,找不到就报错。 - 参数(argument)
参数完全由对应的可执行程序进行解析,但是在其中可能有很多的坑。
1.通配符展开(globbing)
2.变量展开
3.Shell中的变量
4.双引号与单引号
双引号中的参数还是会被展开,单引号中的参数保持原来的字符串传给可执行程序。 - 工作路径(work directory)
启动命令的路径相当于当前路径pwd
输入输出的重定向
任何一个进程,标准输入/标准输出/标准错误都和他绑定在一起。
标准输入
当一个命令不给他参数的时候,它可以从标准输入中读取。一般的标准输入方式 stdin file descriptor=0 使用<或者<<
cat > 1.txt << EOF
标准输出和标准错误
标准输出方式stdout file descriptor=1 使用>或者>>
标准错误方式stderr file descriptor=2 使⽤用2> 或者 2>>
例如
ls > 1.txt
ls 2>1.txt
ls aaa >1.txt 2>&1
我们知道,在Unix系统中,一切皆文件。它读取命令的方式是从右到左读取的。上面的第三条命令执行先去把标准错误重定向到标准输出上,然后在执行前面重定向到1.txt
文件中。我的目录下没有aaa
这个文件,所以在1.txt
文件中打印出了标准错误。
管道
管道的操作我们平常都很熟悉了,比如
cat file.sh | grep class
这里使用的方式的其实是fork了两个进程,cat进程执行完之后的结果输入给grep命令,然后grep执行完后返回结果。
比如我们常见的几种管道操作有
ls | grep class | wc -l //统计当前目录下的class文件数量
ps aux | grep java | awk '{print $2}' | xargs kill -9 //kill 所有的java进程
对于重定向而言,我们还可以使用tee
命令重定向某个操作日志到日志文件中,同时打印在终端。比如像
mvn -X complie | tee output.log
网友评论