shell相关3--------shell脚本的执行方式

以前总是搞乱了,最近有时间正好整理一番。。。。。。。。。。。。。

举例前,先描述一下准备工作,以便更好理解

[root@localhost shell]# pwd
/tmp/shell
[root@localhost shell]# ls
hello.sh
[root@localhost shell]# cat hello.sh
#!/bin/bash
echo "hello world!"
sleep 100
echo "finish!"
[root@localhost shell]# ps -ef|grep -v grep |grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

方法1:./(在当前的工作目录下执行)

进入到shell脚本所在目录(/tmp/shell)通过./来执行脚本

[root@localhost shell]# ./hello.sh &
[1] 10462
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10462 10393  0 15:54 pts/2    00:00:00 /bin/bash ./hello.sh
100s后.............
[root@localhost shell]# finish!
[1]+  終了                  ./hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

方法2:sh或bash

--------------------sh-----------------

[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# sh hello.sh &
[1] 10520
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep sh
root      8714     1  0  7月26 ?      00:00:00 /usr/sbin/sshd -D
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10520 10393  0 16:04 pts/2    00:00:00 sh hello.sh
100s后.............
[root@localhost shell]# finish!
[1]+  終了                  sh hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep sh
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

--------------------bash-----------------
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# bash hello.sh &
[1] 10543
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10543 10393  0 16:09 pts/2    00:00:00 bash hello.sh
100s后.............
[root@localhost shell]# finish!
[1]+  終了                  bash hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

 方法3:以绝对路径的方式去执行bash shell脚本
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# /tmp/shell/hello.sh &
[1] 10507
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10507 10393  0 16:02 pts/2    00:00:00 /bin/bash /tmp/shell/hello.sh
100s后.............
[root@localhost shell]# finish!
[1]+  終了                  /tmp/shell/hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

方法4:.
在当前的shell环境中执行bash shell脚本
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# . hello.sh &
[1] 10612
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10612 10393  0 16:25 pts/2    00:00:00 bash
[root@localhost shell]# finish!
[1]+  終了                  . hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

方案5:source
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# source hello.sh &
[1] 10645
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10645 10393  0 16:31 pts/2    00:00:00 bash
[root@localhost shell]# ps -ef|grep -v grep|grep hello
[root@localhost shell]# ps -ef|grep -v grep|grep hello*
[root@localhost shell]# finish!
[1]+  終了                  source hello.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

方法1,2,3执行shell脚本时都是在当前shell(称为父shell)开启一个子shell环境,
就在这个子shell环境中执行。shell脚本执行完后子shell环境随即关闭,然后又回到父shell中。

方法4,5则是在当前shell中执行的。

两者区别:在当前父进程下的子进程中执行,子进程完成后,子进程中的各项变量或操作将会结束而不会传回到父进程中
前者只作用于子进程本身,后者则作用于整个父进程。
因此,如要想不注销系统,并让全局配置文件生效,则必须用source命令:
比如说: 在全局配置文件中/etc/profile添加了JAVA_HOME,要让他对整个环境生效
export JAVA_HOME=/usr/Java/jdk1.7.0_75
就必须执行source /etc/profile

为了搞清楚另外一个概念,基于方法2,对shell文件修改:

原shell脚本(hello.sh),有可执行权限。
#!/bin/bash
echo "hello world!"
sleep 100
echo "finish!


修改如下
创建新shell脚本(hello1.sh)没有可执行权限
echo "hello world!"
sleep 100
echo "finish!
对hello1.sh做如上重复动作

[root@localhost shell]# ll
合計 8
-rwxr-xr-x. 1 root root 57  7月 27 15:46 hello.sh
-rw-r--r--. 1 root root 44  7月 27 16:12 hello1.sh

--------------------sh-----------------
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# sh hello1.sh &
[1] 10579
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep sh
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10579 10393  0 16:19 pts/2    00:00:00 sh hello1.sh
[root@localhost shell]# finish!
[1]+  終了                  sh hello1.sh
[root@localhost shell]# ps -ef|grep -v grep|grep sh
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

--------------------bash-----------------
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
[root@localhost shell]# bash hello1.sh &
[1] 10593
[root@localhost shell]# hello world!
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash
root     10593 10393  0 16:21 pts/2    00:00:00 bash hello1.sh
[root@localhost shell]# finish!
[1]+  終了                  bash hello1.sh
[root@localhost shell]# ps -ef|grep -v grep|grep bash
sabopeu+  8906  8905  0  7月26 pts/2  00:00:00 -bash
root     10393 10392  0 15:19 pts/2    00:00:00 bash

总结:

若是以方法2的方式来执行,那么,可以不必事先设定shell的执行权限,
甚至都不用写shell文件中的第一行(指定bash路径)。因为方法三是将hello.sh作为参数传给sh(bash)命令来执行的。

这时不是hello.sh自己来执行,而是被人家调用执行,所以不要执行权限。那么不用指定bash路径自然也好理解了