使用source执行shell脚本和直接执行的区别

Jicheng's Blog / 2023-08-28 / 原文

使用 source 命令和 ./ 形式来执行 shell 脚本有一些重要的区别:

  • 使用 ./ 形式执行 shell 脚本时,系统会创建一个新的子进程(不是子线程)来执行脚本。这个子进程会继承父进程(当前 shell)的环境,但脚本内所做的任何修改都只会在子进程中生效,不会影响到父进程(当前 shell)。

  • 使用 source 命令(或 .)执行脚本时,脚本内容会在当前进程(当前 shell)的上下文中执行,而不会创建新的子进程。这意味着脚本中的变量、函数等的更改会直接影响到当前 shell。

这种差异可能会影响脚本中的变量作用域、环境变量的更改以及对当前 shell 的影响。

  1. 作用域:

    • source. 使用 source 命令(或 .)来执行脚本时,脚本在当前 shell 环境中执行。这意味着,脚本中的任何变量、函数定义等在执行后仍然存在于当前 shell 中。
    • ./ 使用 ./ 来执行脚本时,系统会创建一个新的子 shell 来执行脚本。脚本中的变量、函数定义等只在子 shell 中有效,执行结束后不会影响父 shell 环境。
  2. 环境变量:

    • source. 执行脚本时,脚本可以修改当前 shell 环境的环境变量,这些变化将在脚本执行后继续存在。
    • ./ 子 shell 在执行脚本时会继承父 shell 的环境变量,但脚本中对环境变量的更改仅在子 shell 内有效,不会影响父 shell。
  3. 函数和别名:

    • source. 脚本中定义的函数和别名会在执行后继续在当前 shell 中存在,可以在之后的命令中继续使用。
    • ./ 子 shell 中定义的函数和别名只在子 shell 中有效,执行结束后不会影响父 shell。
  4. 退出状态:

    • source. 脚本执行的退出状态会影响当前 shell 环境。
    • ./ 子 shell 的退出状态不会影响父 shell。

综上所述,如果您希望脚本中的变量、函数等更改影响到当前 shell 环境,您可以使用 source 命令(或 .)来执行脚本。如果您只需要执行脚本而不需要在当前 shell 环境中保持任何更改,您可以使用 ./ 形式执行脚本。