当前位置: 首页 > 面试题库 >

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

卫振
2023-03-14
问题内容

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(或其别名.)时,您将bash脚本加载并执行 当前 bash进程中。所以你可以

  • 读取在源脚本中设置的变量,
  • 使用其中定义的功能。
  • 甚至在脚本执行的情况下执行fork和/或子进程。

调用时sh,您将启动一个 fork (子进程或 进程),该 fork
运行新的会话/bin/sh,通常是的符号链接bash。在这种情况下,子脚本完成时将删除由子脚本设置的环境变量

注意sh可能是到 另一个 外壳的符号链接。

一个小样本

例如,如果要通过特定方式更改 当前工作目录 ,则无法执行

$ 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将在一个 subshel​​l中 运行。

但:

$ 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 函数示例(基于 bash
Associative Array的
bash完成)。 __

执行水平 $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 <<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 )是相同的标识符。并非总是如此。)

$ ./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

并进行 最终 测试

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

…您可能会注意到两种语法之间的行为 有所不同 。;-)



 类似资料:
  • 我正在使用webpack来配置源代码映射。我想知道有人能澄清“val”和“evar-source-map”之间的区别吗?我个人看不出有什么区别。

  • 问题内容: 和之间有什么区别? 问题答案: 在当前进程中运行脚本,因此,即使脚本完成之后,所有变量分配也都保留为变量(并且不必显式地“ d”)。 只是在子进程中运行脚本,脚本完成后,分配的所有变量都会消失。

  • 问题内容: 使用Java编译器()时,我们可以指定两种兼容性。一个正在使用,另一个正在使用。两者有什么区别? 例如和? 另外,在任何情况下我们使用不同的源和目标兼容性级别吗? 问题答案: 从javac文档: -source 指定接受的源代码版本。 -target 生成针对指定版本的VM的类文件。类文件将在指定的目标和更高版本上运行,但不会在VM的早期版本上运行。 在您的示例中: 这将用于确保源代码

  • 本文向大家介绍使用PropTypes和Flow有什么区别?相关面试题,主要包含被问及使用PropTypes和Flow有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 Flow 是一个针对react项目所有 JavaScript 代码的静态类型检测器,需要单独添加依赖并手动运行 PropTypes是针对组件级别的类型检测

  • 我是Rust的新手。我认为用于将标识符导入当前范围,用于声明外部模块。但是这种理解(可能是错误的)对我来说没有任何意义。有人能解释一下为什么Rust有这两个概念以及适合使用它们的情况吗?

  • 问题内容: 我想知道使用ReentrentLock和Synchronized(object)有什么大不同吗? 为什么叫reentrentLock?允许来自同一线程的递归调用? 问题答案: 我想知道使用和会有很大的不同。 主要区别在于: 与锁定/解锁绑定到源代码的块结构。无论您如何执行此操作,退出块时都会释放一个锁。例如,如果块由于意外的异常而终止,它将被释放。 使用显式锁定不是这种情况,因此您可以