使用`sh`和`source`有什么区别? [英] What is the difference between using `sh` and `source`?
问题描述
sh
和source
有什么区别?
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).
推荐答案
调用source
(或其别名.
)时,您会在 current 中加载并执行bash脚本 bash进程.因此,您可以
When you call source
(or its alias .
), you load and execute a bash script into the current bash process. So you can
- 读取在源脚本中设置的变量
- 使用其中定义的功能.
- 甚至在脚本执行此操作的情况下执行fork和/或子进程.
调用sh
时,将启动运行新会话/bin/sh
的 fork (子过程或 child ),该会话通常是象征性的链接到bash
.在这种情况下,子脚本完成时,将删除由子脚本设置的环境变量.
When you call sh
, you initiate a fork (sub-process or child) that runs a new session of /bin/sh
, which is usually a symbolic link to bash
. In this case, environment variables set by the sub-script would be dropped when the sub-script finishes.
警告:sh
可能是到另一个外壳的符号链接.
Caution: sh
could be a symlink to another shell.
例如,如果您想以特定方式更改当前工作目录,则无法执行
For example, if you want to change current working directory by a specific manner, you could not do
$ 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
将在 subshell 中运行.
because current working dir is part of environment and myCd2Doc.sh
would run in a subshell.
但是:
$ 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
函数的小样本(使用
I wrote a little sample of mycd
function (with bash completion based on bash Associative Array).
$ 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 <<eoqlvl2 >qlvl2.sh
#!/bin/bash
export startLevel
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
((SHLVL<5)) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh
$ ./qlvl2.sh
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.
$ source qlv2.sh
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.
一点点
$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983
(当前 PID ($$
== 进程ID )是与 SID (会话ID ).并非总是如此.)
( Current PID ($$
== process Id) are same identifier than SID (session ID). It's not alway true.)
$ ./qlvl3.sh
This is level 2.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10266 pts/10 S+ 0:00 \_ /bin/bash ./qlvl3.sh
10267 pts/10 R+ 0:00 \_ ps --sid 8983 fw
$ . qlvl3.sh
This is level 1.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10428 pts/10 R+ 0:00 \_ ps --sid 8983 fw
点.
是source
的别名.因此,两个命令之间的唯一区别是将 slash
替换为 space
.
Dot .
is an alias of source
. So the only difference between two command are slash
replaced by space
.
$ printf %b '\43\41/bin/bash\necho Ending this.\nsleep 1;exit 0\n' >finalTest.sh
$ bash finalTest.sh
Ending this.
$ source finalTest.sh
Ending this.
...您可能会注意到两种语法之间的不同行为. ;-)
... You may notice a different behaviour between the two syntaxes. ;-)
这篇关于使用`sh`和`source`有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!