标题中的命令都可以用来执行一个文件,如脚本(.sh .pl .tcsh等)或一个配置文件(.bashrc .vimrc等)。但它们是有区别的。其中,
$ . filename
$ source filename
是在当前的shell中运行,而
$ /absolute/path/to/filename
$ ./filename
$ sh filename (或者bash, tcsh等)
则是到一个新建的子shell中去运行。
差别体现在,当你运行的文件中有变量声明时,在前一种情况,这些新变量的值会被保留在当前shell中;而在后一种情况,当你的文件被执行完后,子shell被关闭回到当前shell,那些新变量的值会随子shell一齐被删除掉。
因此,我们在配置环境变量时一般都要用第一种方式运行配置文件,而如果用第二种方式将会无效。
如果你试图监视子shell中的变量定义情况,那么就不要期望着用第二种方式运行后还能echo出它的值,而你只能是在你的被执行文件中对你关心的变量使用echo命令,这样才有效。
同样需要注意的是,反过来,当前shell(父shell)的所有变量却可以被其子shel通通l继承下来。
----------------------------------------------------------------------------------
sh filename与./filename的区别在于
“在一般的linux系统当中(如redhat),使用sh调用执行脚本相当于打开了bash的POSIX标准模式(等效于bash的 --posix 参数),一般的,sh是bash的“子集”,不是子集的部分。bash程序执行,当“$0”是“sh”的时候,则要求代码遵循一定的规范,当不符合规范的语法存在时,则会报错,所以可以这样理解,“sh”并不是一个程序,而是一种标准(POSIX),这种标准,在一定程度上保证了脚本的跨系统性。”
[root@centos ~]# cat test.sh
#!/bin/bash
grep -wv -f <(echo '1 2 3 5 9'|sed 's/\s/\n/g') <(seq 1 10)
[root@centos ~]#
[root@centos ~]# sh test.sh
test.sh: line 2: syntax error near unexpected token `('
test.sh: line 2: `grep -wv -f <(echo '1 2 3 5 9'|sed 's/\s/\n/g') <(seq 1 10)'
[root@centos ~]#
[root@centos ~]# bash --posix test.sh
test.sh: line 2: syntax error near unexpected token `('
test.sh: line 2: `grep -wv -f <(echo '1 2 3 5 9'|sed 's/\s/\n/g') <(seq 1 10)'
[root@centos ~]#
[root@centos ~]# bash test.sh
4
6
7
8
10
[root@centos ~]#