Ubuntu shell 脚本执行

ubuntu 执行脚本命令 使用bash xxx.sh 和直接 . xxx.sh运行脚本两种方式有什么区别

在 Ubuntu(以及其他 Linux/Unix 系统)中,使用 bash xxx.sh. xxx.sh(即 source xxx.sh)运行脚本有本质的区别。

主要的区别在于 脚本运行的上下文环境 以及 对当前 Shell 的影响

核心区别对比表

特性bash xxx.sh. xxx.sh (或 source xxx.sh)
执行环境启动一个新的子 Shell (Subshell)在当前 Shell 进程中执行
环境变量脚本内的变量修改仅在子 Shell 有效,脚本结束即失效脚本定义的变量/函数会保留在当前 Shell 中
目录切换脚本内的 cd 命令只影响子 Shell脚本内的 cd 命令会改变当前 Shell 的路径
进程 ID ($$)脚本运行时拥有一个新的 PIDPID 与当前 Shell 相同
权限要求需要读取权限 (Read)需要读取权限 (Read)
主要用途执行一次性任务,避免污染当前环境加载配置文件、环境变量、函数库

详细解析

1. bash xxx.sh (子 Shell 执行)

当你运行 bash xxx.sh 时,系统会启动一个新的 bash 进程(子 Shell)来读取并执行脚本中的命令。

  • 隔离性:脚本中定义的变量、别名或函数在脚本执行完毕后会随子 Shell 一起销毁,不会 影响你当前的终端环境。
  • 目录切换:如果脚本里写了 cd /tmp,只有那个子 Shell 会进入 /tmp。脚本执行完后,你当前的终端依然停留在原来的目录下。
  • 适用场景:绝大多数应用程序脚本、安装脚本、数据处理脚本。

2. . xxx.sh (当前 Shell 执行 / Source)

. 命令(点命令)是 source 命令的简写。当你运行 . xxx.sh 时,脚本中的命令是直接在 当前 的 Shell 进程中逐行执行的,就像是你手动把脚本里的每一行命令敲进终端一样。

  • 持久性:脚本中定义的变量、导出的环境变量(export)、函数都会直接加载到你当前的 Shell 中,并一直保留直到你关闭终端。
  • 目录切换:如果脚本里执行了 cd /var/log,脚本运行完后,你会发现你的终端提示符已经变到了 /var/log 目录下。
  • 适用场景
    • 加载配置文件(如 ~/.bashrc~/.bash_profile)。
    • 激活虚拟环境(如 Python 的 source venv/bin/activate)。
    • 导入常用的函数库供当前会话使用。

举例说明

假设有一个脚本 test.sh,内容如下:

#!/bin/bash
cd /tmp
my_var="Hello World"
echo "Inside script: PID = \$$"

(1) 使用 bash test.sh 运行:

$ echo "Current PID = \$$"
Current PID = 1234
$ bash test.sh
Inside script: PID = 5678  <-- PID 不同,是子进程
$ echo $my_var
                           <-- 为空,变量没带出来
$ pwd
/home/user                 <-- 目录没变

(2) 使用 . test.sh 运行:

$ echo "Current PID = \$$"
Current PID = 1234
$ . test.sh
Inside script: PID = 1234  <-- PID 相同,是同一进程
$ echo $my_var
Hello World                <-- 变量被保留了
$ pwd
/tmp                       <-- 目录被改变了

总结

  • 如果你只是想运行一个程序,并且不希望它弄乱你的环境变量或当前目录,请使用 bash xxx.sh(或者给脚本 +x 权限后直接 ./xxx.sh)。
  • 如果你想加载配置或者让脚本改变当前 Shell 的状态(例如设置环境变量),请使用 . xxx.sh