gpt4 book ai didi

bash - 在 bash 脚本中设置别名

转载 作者:行者123 更新时间:2023-11-29 09:19:26 28 4
gpt4 key购买 nike

我正在尝试在脚本中创建别名,如下所示:

#!/bin/bash
shopt -s expand_aliases

#Currently just using 'git' to try and get it working
#It'll be replaced with the following line when it works
#compgen -c | while read x;
echo 'git' | while read x;
do
a=`echo $x | tr '[:lower:]' '[:upper:]'`;
echo $a;
echo $x;
if [ "$a" != '' ]
then
echo 'got here';
alias $a=$x;
alias;
GIT;
fi
done

虽然一个简单的测试脚本有效(testme 被添加到我当前 shell 的别名中):

#!/bin/bash
shopt -s expand_aliases
alias testme="echo It Worked"
alias
testme

第一个脚本的输出:

GIT
git
got here
alias GIT='git'
alias grep='grep --colour=auto'
alias ls='ls --color=auto'
GIT: command not found

GIT 出现在别名中,但无法执行。我试过用 调用它。 ./script.shsource script.sh。我做错了什么?

最佳答案

这很可能是 何时 扩展别名的问题。 bash 手册页有以下内容:

The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input before executing any of the commands on that line. Aliases are expanded when a command is read, not when it is executed. ...

手册页中有更多信息,但是当在 while 循环中执行复合语句(例如列表)时,扩展将在首次读取输入时发生,而不是在执行时发生。由于在读取输入的时候没有定义GIT,所以会报错。

以下片段显示了问题:

#!/bin/bash
shopt -s expand_aliases

while read x; do
a=`echo $x | tr '[:lower:]' '[:upper:]'`
alias $a=$x
GIT # <--- this fails to execute git
done < <(echo 'git')

GIT # <--- this executes git

一旦 while 循环执行完毕,别名就可用了。手册页中的详细信息有点粗略,但似乎适用于函数中定义的别名的注释。

此外,在使用诸如 echo foo | 的语法时要小心在阅读 x 时;做东西;完成while 循环将在子 shell 中执行,在子 shell 中所做的任何更改都不会在 while 循环之外持续存在。上面的示例显示了一种方法,使 while 循环在当前 shell 中执行,但从执行的命令中获取输入。

更新:

如果上面的脚本以其原始形式编写,它将如下所示:

#!/bin/bash
shopt -s expand_aliases

#Currently just using 'git' to try and get it working
#It'll be replaced with the following line when it works
#compgen -c | while read x;

echo 'git' | while read x; do
a=`echo $x | tr '[:lower:]' '[:upper:]'`
alias $a=$x
GIT # <--- this fails to execute git
done

GIT # <--- this also fails executes git because the alias' were set in a subshell.

在这种情况下,永远不会执行别名。这样做的原因是管道 | 启动了一个新的子 shell 并将进程链接在一起。 echo 在一个进程中运行,while read ... 在另一个进程中运行,由管道链接。设置别名时,它们是在运行 while 循环的子 shell 进程的环境中设置的。但是,当 while 循环完成时,该进程终止并且其环境以及对其环境所做的任何更改(例如添加别名)都被丢弃。因此,第二次尝试执行 GIT 将失败,因为别名信息已被丢弃。

当您使用第一个脚本中显示的拓扑时,while 循环在当前脚本中运行,因此对环境所做的任何更改在循环结束后仍然存在。

如果您执行您的脚本,而不是采购它,您也会注意到这种行为。如果您希望能够像这样在脚本中配置一组别名,运行脚本,让它们在您的环境中可用,您会遇到同样的问题,因为您的脚本在父 shell 的单独进程中运行,创建别名,随后在脚本退出时被丢弃。

$ ./create_aliases
$ alias # <--- Ooops, no aliases defined.

你必须像这样获取你的脚本,它将在当前进程中运行脚本的内容,从而修改当前环境。

$ source ./create_aliases
$ alias # <--- Yay, new aliases present.

这就是为什么 bash 会源文件如 ~/.bashrc,这样你在那个文件中所做的更改将存在于当前环境中。

关于bash - 在 bash 脚本中设置别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15915684/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com