Linux Shell编程 | 你真的了解Shell脚本执行方式吗?我看一半人还未必清楚

人生苦短,务必性感。

            目录

一、执行shell脚本方式多样化

二、sh和bash区别

三、如果脚本的首行指定的解释器不是#!/bin/bash呢

四、.sh不是shell脚本后缀吗?

五、切换路径的影响

六、Shell父进程子进程问题

说的再多,不如动手试试来的明白。

一、执行shell脚本方式多样化

Shell 就是一种脚本语言,我们编写完源码后不用编译,直接运行源码即可。

比如/home/bin/下有个脚本 test.sh

#!/bin/bash
echo "hello world!"

第一种,以绝对路径方式去执行shell脚本

test.sh无执行权限时,执行/home/bin/test.sh,执行失败

我们给脚本赋权,chmod +x tets.sh,再次执行/home/bin/test.sh,执行成功

去掉首行解释器,再次执行,执行失败

其实,以绝对路径方式去执行shell脚本,也可以使用`pwd`命令

注意:pwd前后的 ` 不是英文的单引号,

而是英文输入法下的“~”同一个按键下面的那个符号,就在键盘esc下面那个键

总结:使用绝对路径方式必须为脚本首行指定解释器,也要给脚本添加执行权限

---------------------------------------------------------------------------------------------------------

第二种,最常用的执行方式,sh test.sh

test.sh无执行权限时,执行sh test.sh成功,说明sh方式不需要脚本拥有执行权限

去掉第一行#!/bin/bash ,再执行sh test.sh,仍能成功,

说明这是将test.sh作为参数传给sh(bash)命令来执行的,所有不必再第一行指定解释器

总结:sh方式不必为脚本首行指定解释器,不必给脚本添加执行权限

---------------------------------------------------------------------------------------------------------

第三种,以. 或 source 执行脚本

当test.sh未赋予执行权限时,执行失败

我们给test.sh赋执行权限,再次执行成功了

我们去掉首行解释器,再次执行,也是成功的

如果用. test.sh执行脚本,需要注意:点号.和文件名中间有一个空格

总结: . 或souece方式不必为脚本首行指定解释器,但必需给脚本添加执行权限

---------------------------------------------------------------------------------------------------------

第四种,以. / 执行脚本

这种必须进入脚本当前路径下,执行./test.sh,成功。这种执行方式必须给脚本赋下执行权限

使用./方式我们一般会在首行指定解释器,好让系统查找到正确的解释器

总结: ./方式必须为脚本首行指定解释器,也必需给脚本添加执行权限

---------------------------------------------------------------------------------------------------------

二、sh和bash区别

#!/bin/sh 和#!/bin/bash

#!是一个特殊标记,说明这是一个可执行的脚本,#!后面跟是脚本的解释器程序路径。

除了第一行,其他以#开头都表示注释。

那他们究竟有没有区别呢?

sh 遵循POSIX规范:“当某行代码出错时,不继续往下解释”。

bash 就算出错,也会继续向下执行。

简单说,sh是bash的一种特殊的模式,sh就是开启了POSIX标准的bash, /bin/sh 相当于 /bin/bash --posix

我们常用的Centos,/bin/sh都是指向/bin/bash的符号链接(其它Linux发行版本这里不做分析,没怎么使用过)

ln -s /bin/bash /bin/sh

看下图,其实 sh就是bash,我们man sh  manbash也可以看出没啥区别,个人惯用#!/bin/bash

总结:随便用

三、如果脚本的首行指定的解释器不是#!/bin/bash呢

上面我们有说到,sh是一个shell,运行sh test.sh,表示我使用sh来解释这个脚本。

如果我运行./test.sh,它一般会查找脚本第一行是否指定了解释器,如果没指定,那么就用当前系统默认的shell(大多数linux默认是bash),如果指定了解释器,那么就将该脚本交给指定的解释器。

我们修改下test.sh代码

#!/usr/bin/python
print("Hello World")

那么你运行./test.sh,结果是Hello,但是如果你运行sh a.run,会报语法错误,

因为这是一个python脚本,sh看不懂。

有人提出疑问,

四、.sh不是shell脚本后缀吗?

其实,Linux系统不是通过扩展名来识别文件类型的,在Linux中,带有扩展名的文件,只能代表程序的关联,并不能说明文件是可以执行,

给Shell脚本加.sh后缀只是一种规范和习惯,后缀我们也可以随意命名,甚至不写后缀。

我们把test.sh改为test执行以下看看,仍能成功

五、切换路径的影响

脚本在/home目录下 ,test.sh内容为:

#!/bin/sh
cd /home/peim
pwd
ls -l

如果在/home下执行./test.sh 或者sh test.sh,可以看到/home/peim/下的内容,但shell退出后还是在原来的工作目录/home。

如果/home下执行source test.sh,可以看到/home/peim/下的内容,且shell退出后在目录/home/peim下。

六、进程问题

source 命令和 sh 命令的执行机制是不同的:

  • source 在当前 Shell 环境下来执行脚本文件中的内容

  • sh        重新开辟一个新的子Shell,在子Shell 中执行脚本文件中的内容,执行完毕后再返回 父Shell

什么意思呢,举一个非常简单的例子:

我们在test.sh脚本最后一行添加exit 0,再用sh 和source执行看一下

#!/bin/sh
cd /home/peim
pwd
ls -l
exit 0

使用sh或./执行,可以看出像什么都没发生一样,感觉加上exit 0也没有任何影响

我们再使用source执行一下,可以看到居然退出到登录界面了

补充:

子shell里面的变量父shell无法使用,对环境变量的修改也不影响父shell。

父shell中的局部变量,子shell无法使用,只有父shell的环境变量,子shell能够使用。

sh 创建子shell和当前的shell并行执行,子shell中执行,脚本设置的变量不会影响当前shell。

一旦子Shell中的执行完毕,此子Shell随即结束,回到父Shell中,不会影响父Shell原本的环境。

子Shell环境拥有与父Shell相同的环境变量、标准输入、输出、错误。

未完

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我自人间漫浪

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值