shell脚本的三种执行方式和区别

执行方式

  1. 直接使用绝对,相对路径

这种是平时我们最常用的方法,例如:

./test.sh
/home/thammer/test.sh

甚至PATH目录里面的,如系统自带的命令,也就是无需指定路径,直接使用命令,也是这种形式,只不过命令在bash这个解释器内部给补全了而已。

  1. 使用bash或者其他你系统带的shell解释器程序跟shell脚本,例如:
bash test.sh
zsh ./test.sh

这种和第一种区别不大,稍微有区别的地方是,如果系统带有多种shell解释器,那么这里可以指定你想要的那种,否则用的就是默认的。

  1. 使用内置的source命令
source ./test.sh

source命令是shell内置命令,类似的还有cd,alias,fg等等。

三种方式的区别

第三种source这种方式执行shell脚本和前两者有非常大的区别,它直接在当前shell解释器进程加载并执行命令,共享了当前解释器进程的环境变量,而前两种方式都是在当前shell解释器进程中开子进程,另起一个shell解释器,然后执行shell脚本。

如何理解?首先当我们打开一个终端,可以理解为创建并运行了一个bash程序(是否为bash和/etc/passwd的配置相关,不做分散解释),它提供的标准输入,标准输出,标准出错3个IO和用户进行交互。如果我们执行ps命令,可以看到当前bash程序的pid。

thammer@exc:~/CLionProjects/shelltest$ ps
PID TTY TIME CMD
17450 pts/1 00:00:00 bash
19934 pts/1 00:00:00 ps

可以看到当前bash的pid为17450,那么我们可以在shell脚本中输出当前进程id,就知道是开启了子进程,还是直接在当前进程执行的shell脚本了。在shell中,获取当前进程id的方法是通过内置的变量$。使用$$(第一个是shell语法中引用变量的关键字符,第二个就是内置变量$,表示当前进程id)就获取到了当前进程pid。test.sh如下:

#!/bin/bash
echo $$

按照3种执行方式执行,结果如下:

thammer@exc:~/CLionProjects/shelltest$ ./test.sh
20129
thammer@exc:~/CLionProjects/shelltest$ bash test.sh
20132
thammer@exc:~/CLionProjects/shelltest$ source test.sh
17450

只有最后这个pid和当前bash的进程pid一样。

有何影响

由于source未开辟新的进程,所以它可以看到当前进程的环境变量,也可以修改并影响当前bash进程的环境变量,而前两种种方式不能。验证,首先在当前shell命令赋值一个变量,

VAR1=hello

通过3中方式执行如下shell脚本,test.sh

#!/bin/bash
echo $VAR1
VAR1=world

执行

thammer@exc:~/CLionProjects/shelltest$ VAR1=hello
thammer@exc:~/CLionProjects/shelltest$ ./test.sh
thammer@exc:~/CLionProjects/shelltest$ echo $VAR1
hello
thammer@exc:~/CLionProjects/shelltest$ source ./test.sh
hello
thammer@exc:~/CLionProjects/shelltest$ echo $VAR1
world
posted @   thammer  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示