马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
source 命令 (或者它的POSIX等效命令 .):在当前 Shell 环境中执行脚本
简单来说,source 命令的作用是:在当前的 Shell 会话中读取并执行指定文件中的命令。
这意味着,被 source 执行的脚本中的所有命令,就似乎是你直接在当前的命令行提示符下逐行输入并执行的一样。
核心关键点:
- 当前 Shell 环境 (Current Shell Environment): 这是理解 source 的核心。当你登录系统或者打开一个终端时,你就进入了一个 Shell 环境。这个环境包罗了许多东西,比如:
- 环境变量 (Environment Variables): 像 PATH, HOME, USER, PS1 (命令提示符) 等。
- Shell 变量 (Shell Variables): 仅在当前 Shell 内部有效的变量。
- 定义的函数 (Defined Functions): 你在当前 Shell 中创建的函数。
- 别名 (Aliases): 你设置的命令别名,比如 alias ll='ls -alF'。
- 当前工作目录 (Current Working Directory): 你用 pwd 命令看到的目录。
- source 的举动:
- 当使用 source some_script.sh (或者 . some_script.sh) 时,Shell 会打开 some_script.sh 文件,逐行读取其中的命令,并在 当前的这个 Shell 进程中 执行它们。
- 因此,如果 some_script.sh 中定义了新的环境变量、Shell 变量、函数,或者修改了已有的,这些改变会直接反映并持久地作用于你当前的 Shell 会话。
- 如果脚本中有 cd /some/directory 这样的命令,你的当前工作目录也会改变。
与直接执行脚本的区别 (至关重要!)
这可能是最容易混淆的地方,也是 source 最能体现其代价的地方。
当你像下面这样执行一个脚本时:
- ./myscript.sh
- # 或者
- bash myscript.sh
复制代码 操纵系统会创建一个新的进程 (一个子 Shell) 来执行 myscript.sh。
- 这个子 Shell 会继承父 Shell (你当前的 Shell) 的一部门环境副本。
- 脚本在子 Shell 中对环境变量、函数、别名、工作目录所做的任何修改,都仅限于谁人子 Shell 内部。
- 一旦子 Shell 执行完毕并退出,它所做的所有环境修改都会随之消失,不会影响到父 Shell (你当前的 Shell)。
打个比方(帮助理解):
- source myscript.sh: 就像你亲自学习了一套新技能 (脚本里的内容)。学习完成后,这些新技能 (变量、函数等) 成为了你自身本领的一部门,你可以在当前状态下直接使用。
- ./myscript.sh: 就像你聘请了一位临时助手 (子 Shell) 去完成一项任务 (执行脚本)。助手在工作时可能会学习新东西、整理办公室 (改变环境),但当助手完成任务离开后,他学到的东西和对办公室的整理并不会直接转移给你或你的办公室。
source 的典型应用场景:
- 加载设置文件: 这是最常见的用途。
- 比如你的 ~/.bashrc (Bash Shell)、~/.zshrc (Zsh Shell) 或 ~/.profile 文件。当你登录或打开新的终端时,Shell 通常会自动 source 这些文件,以便加载你自定义的环境变量、别名、函数和提示符设置。
- 如果你修改了 ~/.bashrc,为了让修改立刻生效而不用重新登录或打开新终端,你就可以手动执行:
- source ~/.bashrc
- # 或者
- . ~/.bashrc
复制代码
- 激活虚拟环境: 在 Python 开发中,我们常常使用虚拟环境 (如 venv 或 conda)。激活虚拟环境的脚本 (通常是 activate) 就必须使用 source 来执行。
- source myenv/bin/activate
复制代码 这个 activate 脚本会修改 PATH 环境变量,设置一些特定的虚拟环境相干的变量等,这些改变必须作用于当前 Shell,才气让你接下来输入的 python 或 pip 命令指向虚拟环境中的版本。
- 加载包罗函数库或变量定义的脚本:
假设你有一个 my_functions.sh 文件,内里定义了很多有效的 Shell 函数:
- # my_functions.sh
- my_greeting() {
- echo "Hello, $1! Welcome to our Shell world."
- }
- set_my_project_path() {
- export MY_PROJECT_DIR="/opt/my_project"
- echo "MY_PROJECT_DIR set to $MY_PROJECT_DIR"
- }
复制代码 如果你直接 ./my_functions.sh,什么都不会发生(除非脚本里有直接执行的命令)。但如果你 source my_functions.sh:
- source ./my_functions.sh
- my_greeting "Professor" # 调用函数
- set_my_project_path # 设置并导出环境变量
- echo $MY_PROJECT_DIR # 查看环境变量
复制代码 my_greeting 函数和 MY_PROJECT_DIR 环境变量就会在你的当前 Shell 中可用了。
- 在脚本中共享状态: 如果一个脚本需要设置一些变量,然后让调用它的脚本或者当前 Shell 能够访问这些变量,source 就是不二之选。
语法:
- source FILENAME [ARGUMENTS]
- . FILENAME [ARGUMENTS]
复制代码
- FILENAME 是你要执行的脚本文件的路径。
- [ARGUMENTS] 是可选的,可以传递给被 source 的脚本作为位置参数 ($1, $2, …)。
一个小提示:
被 source 的文件通常不需要有执行权限 (不像 ./myscript.sh 那样需要 chmod +x myscript.sh),由于它是由当前的 Shell 直接读取并解释执行的,而不是作为一个独立的可执行程序运行。
需要注意的一点:
由于 source 的脚本会直接影响当前环境,所以要小心。如果被 source 的脚本中有 exit 命令,它会导致你当前的 Shell 退出!如果它意外地修改了重要的环境变量 (比如 PATH 设置错了),可能会让你的当前 Shell 变得难以使用。所以,请确保你 source 的是可信且精确的脚本。
source 命令就像一把钥匙,它打开了 Shell 脚本与当前交互环境之间直接沟通的大门。把握了它,你就能更灵活、更强盛地定制和控制你的 Shell 工作空间。
|