什么是使用`sh`和`source`之间的区别?(What is the difference be

2019-06-21 20:01发布

是什么区别shsource

source: source filename [arguments]
    Read and execute commands from FILENAME and return.  The pathnames
    in $PATH are used to find the directory containing FILENAME.  If any
    ARGUMENTS are supplied, they become the positional parameters when
    FILENAME is executed.

而对于man sh

NAME
       bash - GNU Bourne-Again SHell

SYNOPSIS
       bash [options] [file]

COPYRIGHT
       Bash is Copyright (C) 1989-2004 by the Free Software Foundation, Inc.

DESCRIPTION
       Bash  is  an sh-compatible command language interpreter that executes commands read from the standard input or from a file.  Bash also incorporates
       useful features from the Korn and C shells (ksh and csh).

       Bash is intended to be a conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).

Answer 1:

当你调用source (或它的别名. ), 插入当前 bash进程的脚本。 所以你可以读通过脚本设置变量。

当你调用sh ,你开始运行的一个新的会话 (子进程) /bin/sh ,这通常是一个符号链接bash 。 在这种情况下,当子脚本完成由子脚本设置环境变量将被丢弃。

注意sh可能是一个符号链接到另一个 shell。

一个小样本

例如,如果你想通过特定的方式来改变当前的工作目录 ,你不能这样做

cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof

chmod +x myCd2Doc.sh

这不会做你所期望的:

cd /tmp
pwd
/tmp
~/myCd2Doc.sh
pwd
/tmp

因为当前的工作目录是环境的一部分, myCd2Doc.sh将在一个子shell中运行。

但:

cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
    cd /usr/share/doc
}
eof

. myCd2Doc.source
cd /tmp
pwd
/tmp
myCd2Doc
pwd
/usr/share/doc

(我写的一个小样本mycd功能。)

执行层$SHLVL

cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh

bash qlvl.sh 
This is level 2.

source qlvl.sh 
This is level 1.

小递归

cat <<eoqlvl >qlvl.sh 
#!/bin/bash

export startLevel
echo This is level $SHLVL starded:${startLevel:=$SHLVL}.
((SHLVL<5)) && ./qlvl.sh
eoqlvl
chmod +x qlvl.sh

./qlvl.sh 
This is level 2 starded:2.
This is level 3 starded:2.
This is level 4 starded:2.
This is level 5 starded:2.

source qlvl.sh 
This is level 1 starded:1.
This is level 2 starded:1.
This is level 3 starded:1.
This is level 4 starded:1.
This is level 5 starded:1.

最后的测试:

printf %b '\43\41/bin/bash\necho Ending this.\nexit 0\n' >finalTest.sh

bash finalTest.sh 
Ending this.

source finalTest.sh
Ending this.

...您可能会注意到两者之间的语法不同的行为。 ;-)



Answer 2:

主要的区别是,它们在不同的处理中执行。

所以,如果你source文件foo它做了cd ,采购外壳(例如,在终端的交互shell)受到影响(以及它的当前目录下会发生变化)

如果执行sh foocd不影响采购外壳,只有新创建的sh进程中运行foo

阅读高级Bash脚本编程指南 。

这种差别不是具体到Linux; 每POSIX实现将有它。



Answer 3:

正如其他人所说,当你运行sh test.sh ,任何改变test.sh让你的shell环境不会在过程结束之后仍然存在。

但是,也请注意,未出口环境的任何元素(如变量,别名和shell函数)将不会提供给在代码test.sh当它作为一个子(即执行sh test.sh )。

例如:

$ cat > test.sh
echo $foo
$ foo=bar
$ sh test.sh
$ . test.sh
bar

实施例2:

lap@my-ThinkPad:~$ cat test.sh
#!/bin/sh
cd /etc
lap@my-ThinkPad:~$ sh test.sh 
lap@my-ThinkPad:~$ pwd
/home/savoury
lap@my-ThinkPad:~$ source test.sh 
lap@my-ThinkPad:/etc$ pwd
/etc
lap@my-ThinkPad:/etc$ 


Answer 4:

当您使用sh命令执行程序:

  • 您的终端将使用sh或Bourne shell的执行程序。
  • 创建一个新的过程,因为猛砸使得自身的拷贝。 此子进程具有相同的环境,其母公司,只有进程ID号是不同的。 (此过程称为分叉)
  • 你需要需要有执行权限来执行它(因为它分叉)

当你使用source命令:

  • 你与你的默认解释执行程序
  • 您在当前终端执行的过程中(在技术上你的* nix命令解释)
  • 由于该方案将在目前的终端执行你不需要给它执行权限


文章来源: What is the difference between using `sh` and `source`?