我有很多 BASH 函数,这些函数我已经使用了/etc/bash.bashrc
很长时间了。它们在那里~/.bashrc
、在 和 OSX 中工作~/.bash_profile
,写成这样:
mcdir(){
mkdir "$1";
eval cd "$1";
}
这只是一个简短的例子,我每天都会使用它。它只是创建一个给定的目录并对其进行更改,这样就mkdir "$1" && cd "$1"
可以了......我只是懒惰。
关键是它有效……我知道它有效,因为我已经使用它很多年了。
现在,我最近将其从 my 中删除bashrc
并将其放入/usr/local/bin
as 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;
它实际上并没有改变到目录中。它会给我pwd
和ls -l
,但我根本不会更改目录。
答案1
脚本在子 shell 中运行。它们不能像函数那样影响活动 shell 会话的环境。例如,参见高级 Bash 脚本指南,第 21 章:子 shell:
子 shell 是命令处理器的一个单独实例——壳这会在控制台或在控制台中向您提供提示xterm窗户。正如您的命令在命令行提示符下被解释一样,脚本也类似地被解释批处理命令列表。每个运行的 shell 脚本实际上都是一个子进程(子进程) 的家长壳。
通过使用 chmod 命令打开执行位,可以使 shell 脚本可执行。当 Bash 在搜索命令时找到这样的文件时
$PATH
,它会生成一个子 shell 来执行它。换句话说,执行
filename arguments
相当于执行
bash filename arguments
if
filename
是一个可执行的 shell 脚本。该子 shell 重新初始化自身,因此效果就像调用了一个新 shell 来解释脚本一样,但父 shell 记住的命令位置除外(请参阅hash
中的描述)Bourne Shell 内置函数)由孩子保留。
如果您想使用脚本而不是函数,您可以source
使用它而不是执行它,但老实说,我认为最好坚持使用函数(或别名)来完成您正在做的事情。
也就是说,如果您想重新组织您的代码,~/.bashrc
那么您可以将其分解为单独的文件,然后将source
这些文件从~/.bashrc
,例如,您可以将它们放在本地子目录中,例如~/.bashrc.d
。