BASH 脚本选择性地工作

BASH 脚本选择性地工作

我有很多 BASH 函数,这些函数我已经使用了/etc/bash.bashrc很长时间了。它们在那里~/.bashrc、在 和 OSX 中工作~/.bash_profile,写成这样:

mcdir(){
    mkdir "$1";
    eval cd "$1";
}

这只是一个简短的例子,我每天都会使用它。它只是创建一个给定的目录并对其进行更改,这样就mkdir "$1" && cd "$1"可以了......我只是懒惰。

关键是它有效……我知道它有效,因为我已经使用它很多年了。

现在,我最近将其从 my 中删除bashrc并将其放入/usr/local/binas mcdir(以及chmod +x /usr/local/bin/mcdir)中,因此实际上没有任何更改。在这里,它看起来像这样:

#!/bin/bash

mkdir "$1";
eval cd "$1";

出于所有意图和目的,这应该与上述函数完全相同。问题是它只能起到一半作用。它将创建新目录,但是绝不改变成它。

有谁知道我在这里做错了什么,和/或如何解决它?


我的另一个例子是一个cdd函数...bashrc它看起来像这样:

cdd(){
    cd "$1";
    echo -e "\033[101m" $(pwd) "\033[49m";
    ls -l;
}

这非常有效!但是,当我将它放入自己的脚本中/usr/local/bin并使其可执行时,如下所示:

cd "$1";
echo -e "\033[101m" $(pwd) "\033[49m";
ls -l;

它实际上并没有改变到目录中。它会给我pwdls -l,但我根本不会更改目录。

答案1

脚本在子 shell 中运行。它们不能像函数那样影响活动 shell 会话的环境。例如,参见高级 Bash 脚本指南,第 21 章:子 shell

子 shell 是命令处理器的一个单独实例——这会在控制台或在控制台中向您提供提示xterm窗户。正如您的命令在命令行提示符下被解释一样,脚本也类似地被解释批处理命令列表。每个运行的 shell 脚本实际上都是一个子进程(子进程) 的家长壳。

或者Bash 参考手册,第 3.8 节:Shell 脚本

通过使用 chmod 命令打开执行位,可以使 shell 脚本可执行。当 Bash 在搜索命令时找到这样的文件时$PATH,它会生成一个子 shell 来执行它。换句话说,执行

filename arguments

相当于执行

bash filename arguments

iffilename是一个可执行的 shell 脚本。该子 shell 重新初始化自身,因此效果就像调用了一个新 shell 来解释脚本一样,但父 shell 记住的命令位置除外(请参阅hash中的描述)Bourne Shell 内置函数)由孩子保留。

如果您想使用脚本而不是函数,您可以source使用它而不是执行它,但老实说,我认为最好坚持使用函数(或别名)来完成您正在做的事情。

也就是说,如果您想重新组织您的代码,~/.bashrc那么您可以将其分解为单独的文件,然后将source这些文件从~/.bashrc,例如,您可以将它们放在本地子目录中,例如~/.bashrc.d

相关内容