`sh`和`source`有什么区别?

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). 

Solutions Collecting From Web of "`sh`和`source`有什么区别?"

当您调用source (或其别名)时,您脚本插入 当前的 bash进程中。 所以你可以读取脚本设置的变量。

当你调用sh ,你启动一个fork (子进程),运行新的/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. 

…您可能会注意到两种语法之间的不同行为。 😉

主要区别在于它们在不同的过程中执行。

所以,如果你的文件foo做了一个cd ,源代码shell(例如终端中的交互式shell)就会受到影响(并且它的当前目录将会改变)

如果执行sh foocd不会影响sourcing shell,只有刚创建的sh进程运行foo

阅读高级Bash脚本指南 。

这种差异不是特定于Linux的; 每个Posix实现都会有它。

当你用sh命令执行一个程序时:

  • 您的终端将使用sh或Bourne Shell来执行该程序。
  • 创建一个新的进程,因为Bash自己做一个精确的副本。 此子进程与其父进程具有相同的环境,只有进程标识号不同。 (这个过程称为分叉)
  • 你需要有执行权限来执行它(因为它是分叉的)

而当你使用源码命令时:

  • 你用你的默认解释器执行程序
  • 您在当前终端执行该过程(技术上解释您的* nix命令)
  • 由于该程序将在当前终端执行,您不需要授予执行权限

正如其他人所提到的那样,当你运行sh test.shtest.sh对你的shell环境所做的任何修改都不会在这个过程结束后持续下去。

但是,还要注意,当你的环境中的任何不被导出的元素(例如,变量,别名和shell函数)在test.sh的代码作为子test.sh被执行时(例如sh test.sh )。

例如:

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