Shell 脚本调用脚本的三种方法
创建脚本 first.sh:
echo 'your are in first file'
1.source
echo 'your are in second file'
source first.sh
2.点号.
echo 'your are in second file'
. first.sh
3.sh 命令
echo 'your are in second file'
sh first.sh
三者输出的结果都是:
your are in second file
your are in first file
4.三者的区别
使用 source 命令和点号是等价的,类似于 C/C++ 中的 #include 预处理指令,都是将指定的脚本内容拷贝至当前的脚本中,由一个 Shell 进程来执行。使用sh命令来调用另外的脚本和前面两种方法有着本质的区别。使用sh命令则会开启新的Shell进程来执行指定的脚本,这样的话,父进程中的变量在子进程中就无法访问。参考如下代码:
first.sh 内容如下,访问了 second.sh 中的变量 second。
echo 'your are in first file'
echo 'second:' $second
second.sh内容,通过上面介绍的三种方法来调用first.sh,看看对second.sh的变量second访问有什么区别!
#!/bin/bash
second=lvlv
echo 'your are in second file'
source first.sh
. first.sh
sh first.sh
程序的输出结果是:
[root@server test]# bash second.sh
your are in second file
your are in first file
second: lvlv
your are in first file
second: lvlv
your are in first file
second:
可见,使用sh命令开启一个子进程来调用指定的shell脚本无法访问父进程的变量
5.fork的概念以及常见的shell script执行方式。
fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。
环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程。不管子进程的环境变量如何变化,都不会影响父进程的环境变量。
shell script 常见的执行方式有两种,一种是新产生一个shell,然后执行相应的shell script;一种是在当前shell下执行,不再启用其他shell。
- 新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句
#!/bin/sh
一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。
- 另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。
可以做个测试,我们有一个简单的脚本叫output.sh
echo process ID of output.sh is $$
echo parent process ID of outout.sh is $PPID
第一行输出执行该脚本的shell进程ID
第二行输出其父进程ID
[root@server test]# echo process ID of shell is $$
process ID of shell is 11189
[root@server test]# echo Parent process ID of shell is $PPID
Parent process ID of shell is 11185
我们启动系统的shell窗口并查看该shell的进程ID和父进程ID:
echo process ID of shell is $$
echo Parent process ID of shell is $PPID
执行output.sh
[root@server test]# bash output.sh
process ID of output.sh is 12776
parent process ID of outout.sh is 11189
其进程ID不同于之前的shell进程ID,且父进程ID为之前的shell 进程ID,说明这种执行方式是新产生一个shell,然后执行相应的shell scripts;
再看以source方式执行:
[root@server test]# source output.sh
process ID of output.sh is 11189
parent process ID of outout.sh is 11185
无论是进程ID还是父进程ID都和之前的shell一模一样,说明source命令在当前shell下执行,不再启用其他shell。