Linux bash shell中. & source & ./的区别

53 篇文章 0 订阅
14 篇文章 0 订阅

整理自安全撤退的一句话bash 脚本


BASH脚本可以以 . 或 source内置命令来执行, 也可以直接执行脚本文件(需要首行有#!/path/to/bash并且文件是可执行的), 这两种情况是有一些微妙区别的.

1.以.或source这两个等价的builtin来执行脚本时是在当前的SHELL解释器中直接读取命令来执行, 所以可以通过这个脚本改变当前SHELL的环境变量, 脚本中的exit所退出的也自然是当前这个SHELL, 这一点很可能不是大多数情况下的预期行为

2.而直接执行脚本则会在一个子SHELL进程中读取脚本中的命令执行, 此时只能改变当前这个进程的环境变量, 不能上溯影响其父进程的环境块, 而exit也只是退出这个子进程而已. 


在程序刚开始的地方往往会检查参数的合法性, 如果参数个数, 顺序或其它方面的要求不正确, 程序往往就没办法执行, 此时最经常的用法就是显示程序的usage信息, 然后用exit 1;来提前终止程序. 但这对于用.或source执行脚本的情况来说就会错误地退出当前的shell.

怎么样在任何情况下都能让程序全身而退: SHLVL 变量.它是shell level的简写. 意思是SHELL被嵌套的次数.

[ ! -f $1 ] && { echo "FILE $1 doesn't exist"; [ $SHLVL -gt 1 ] && exit 1; [ $SHLVL -eq "1" ] && return; }

上面这个命令检查了$1 是否是一个普通文件, 如果不是就显示一条错误信息说该文件不存在, 然后检查 $SHLVL是否大于1, 如果是的话就可以安全地用exit退出, 此时后面那句话也就不必执行了, 如果不是的那它的值其实也只能是1了(这个变量是SHELL中的只读变量, 不能以可编程的方法来改变), 这时说明是在当前的shell执行的, 用return;语句退出.


那么是不是两种情况都可以简单地用return; 来退出呢. 不是!

简单地执行下面的脚本(tmp.sh)

#!/bin/bash


{
  return;
}
echo "After return";


如果是以. tmp.sh来执行就没问题, 如果以./tmp.sh来执行则会显示一条错误信息:

./tmp.sh: line 5: return: can only `return' from a function or sourced script

说的很明白, return只能用在直接解释执行的脚本或函数中. 上面的{ ... }只是一个命令组, 不是函数(不要认为是个匿名函数)


在很多的程序语言里, return也的确只能用于函数的返回, 在SHELL编程中它也可以出现在程序最外面层的位置. 只不过这种用法只对所谓sourced 脚本才有特殊语意.

标准的SHELL内置帮助是没有提及这个特殊用法的, 反而前面的错误信息提到了这一点:
bash-2.05b$ help return
return: return [n]
    Causes a function to exit with the return value specified by N.  If N
    is omitted, the return status is that of the last command.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值