script 的执行方式差异(source, sh script, ./script)

不同的script执行方式会造成不一样的结果喔!尤其影响bash的环境很大呢!脚本的执行方式除了前面小节谈到的方式之外,还可以利用source 或小数点(.)来执行喔!那么这种执行方式有何不同呢?当然是不同的啦!让我们来说说!

  • 利用直接执行的方式来执行script

当使用前一小节提到的直接指令下达(不论是绝对路径/相对路径还是${PATH}内),或者是利用bash (或sh)来下达脚本时,该script都会使用一个新的bash环境来执行脚本内的指令!也就是说,使用这种执行方式时,其实script是在子程序的bash内执行的!我们在第十章BASH内谈到 export的功能时,曾经就父程序/子程序谈过一些概念性的问题,重点在于:『当子程序完成后,在子程序内的各项变数或动作将会结束而不会传回到父程序中』!这是什么意思呢?

我们举刚刚提到过的showname.sh 这个脚本来说明好了,这个脚本可以让使用者自行设定两个变数,分别是firstname 与lastname,想一想,如果你直接执行该指令时,该指令帮你设定的firstname 会不会生效?看一下底下的执行结果:

[dmtsai@study bin]$ echo ${firstname} ${lastname} 
    <==确认了,这两个变数并不存在喔!
[dmtsai@study bin]$ sh showname.sh 
Please input your first name: VBird  <==这个名字是鸟哥自己输入的 
Please input your last name:   Tsai

Your full name is: VBird Tsai       <==看吧!在script运作中,这两个变数有生效 
[dmtsai@study bin]$ echo ${firstname} ${lastname} 
    <==事实上,这两个变数在父程序的bash中还是不存在的!

上面的结果你应该会觉得很奇怪,怎么我已经利用showname.sh 设定好的变数竟然在bash 环境底下无效!怎么回事呢?如果将程序相关性绘制成图的话,我们以下图来说明。当你使用直接执行的方法来处理时,系统会给予一支新的bash 让我们来执行showname.sh 里面的指令,因此你的firstname, lastname 等变数其实是在下图中的子程序bash 内执行的。当showname.sh 执行完毕后,子程序bash 内的所有资料便被移除,因此上表的练习中,在父程序底下echo ${firstname} 时, 就看不到任何东西了!这样可以理解吗?

showname.sh 在子程序当中运作的示意图

图12.2.1、showname.sh 在子程序当中运作的示意图

  • 利用source 来执行脚本:在父程序中执行

如果你使用source 来执行指令那就不一样了!同样的脚本我们来执行看看:

[dmtsai@study bin]$ source showname.sh 
Please input your first name: VBird 
Please input your last name:   Tsai

Your full name is: VBird Tsai 
[dmtsai@study bin]$ echo ${firstname} ${lastname} 
VBird Tsai   <==嘿嘿!有资料产生喔!

竟然生效了!没错啊!因为source 对script 的执行方式可以使用底下的图示来说明!showname.sh 会在父程序中执行的,因此各项动作都会在原本的bash 内生效!这也是为啥你不登出系统而要让某些写入~/.bashrc 的设定生效时,需要使用『 source ~/.bashrc 』而不能使用『 bash ~/.bashrc 』是一样的啊!

showname.sh 在父程序当中运作的示意图

图12.2.2、showname.sh 在父程序当中运作的示意图

 

++利用./ 来执行脚本:在父程序中执行
 

./xxxx
使用这个命令需要先将文件提升为可执行的文件才可以进行命令的使用

1如何提升权限,请看这篇总结——————linux用户组以及权限总结

2以下在知乎看到的区别:

如果我直接运行./xxx.sh,首先你会查找脚本第一行是否指定了解释器,如果没指定,那么就用当前系统默认的shell(大多数linux默认是bash),如果指定了解释器,那么就将该脚本交给指定的解释器。例如我下面的代码中,我指定了这是一个python脚本,而不是shell脚本:

#!/usr/bin/python
print("This is Python script")
1
2
那么你如果运行./a.run,结果就是输出一行文字,但是如果你运行sh a.run,会报错:

[feishu@localhost tmp]$ ./a.run 
This is Python Script
[feishu@localhost tmp]$ sh a.run 
a.run: line 2: syntax error near unexpected token `"This is Python Script"'
a.run: line 2: `print("This is Python Script")'


因为这是一个python脚本,sh看不懂(注意,linux下后缀通常不是很严格,.run后缀是我随意命名的,和windows有点区别).回到你的问题,你是写了一个shell脚本,想问./a.sh和sh a.sh区别,这个要看你系统默认shell和脚本了,如果你写的是一个sh ( Bourne shell )脚本而且第一行申明了解释器为sh,那么没区别,但是如果你写的是一个bash(Bourne Again SHell) 脚本,那结果就可能有区别了,因为bash和sh的内置命令、语法等有些不一样。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值