非交互式Bash shell中为什么别名不起作用?

57

我试图在非交互式的Bash shell中使用别名。我已经在~/.bashrc中定义了我的别名,并设置了变量BASH_ENV=~/startUpFile。其中startUpFile文件的内容是source ~/.bashrc

当我执行alias命令时,我可以看到我的别名被识别出来。但是,如果我尝试使用在~/.bashrc中定义的别名,Bash无法识别它,并给出未知命令错误。

在TCSH shell中,这样做相当容易,因为~/.cshrc文件总是被读取。

有任何想法如何在Bash shell中实现此功能吗?


1
这个 答案 很好地解释了 interactivenon-interactive shell 配置。此外,还有一个提示,在 non-interactive 模式下包括 .bashrc - Dmytro
4个回答

56

使用命令shopt -s expand_aliases可以在非交互式shell中扩展别名。


3
直到我把别名定义放在函数定义之前,它才能在函数中使用;似乎在读取函数定义时别名被展开了! - Aquarius Power
6
也许还应该提到,即使使用这个方法,别名仍然不能在包含此语句的实际代码行中使用,因此使用此语句的一行代码将无法起作用。一个解决方法是在命令之间使用换行符而不是分号,如 ssh remote $'shopt -s expand_aliases\nll' - tripleee
1
另一种选择(来自重复问题 - 右侧请参见“相关问题”)是运行 bash -i 以强制 shell 成为交互式的。 - tripleee

16

.bashrc只有交互式shell才会处理。

此外,除非使用shopt设置expand_aliases shell选项,否则别名不会在非交互式shell时扩展。当然,如果使用sh而不是bash调用shell,则会调用POSIX模式。

经常使用别名的人通常将其.bashrc源于其配置文件的末尾,以便别名即使对于非交互式shell也存在。 这可能不是最好的方法,但它非常普遍。

正是这些事情让我相信,在21世纪,我们应该放弃Shell脚本,转而使用像Python这样的完整语言。 它更加可预测。


7
Python 作为一种交互式语言非常糟糕。除非空格符号完全正确,否则您无法剪切/粘贴随机代码片段。然而,tclsh 是一个相当不错的 shell -- 如果您输入的命令不是已知的 tcl 命令,则它具有内置的执行 shell 命令的能力。此外,它的本质使得交互使用变得可行。尽管我很喜欢 Tcl,但对于交互式使用,我仍然更喜欢老式的 bash。遗憾的是 tksh 从未达到逃逸速度。 - Bryan Oakley
/etc/profile 的技巧只适用于被提供 --login 选项的非交互式 shell。 - Vinko Vrsalovic
1
你说得没错,Python并不适合作为交互式语言。你应该使用bash。但是如果你必须写脚本,请使用Python。因为它是一种面向对象的语言,你可以将代码片段重复使用,把它们写成类、方法和函数。脚本编写与编程相同,因此请使用像Python这样功能强大的编程语言。但对于只有两三个命令流水线的交互,bash也可以。 - Michael Dillon
2
观点警报!观点警报!(并不是说Python本身有什么问题——除了它是动态类型的O.o——但Ruby和Perl(以及其他什么)在那个市场上也是很好的竞争者) - user166390
1
你绝对可以在Bash中编写“可重用”的函数... #ThatsHot(){ echo“谢谢,美人。”; }; ThatsHot - Alex Gray

13
你需要:
shopt -s expand_aliases

在指向你的BASH_ENV文件中


3

我曾经遇到过类似的问题,最终发现只需要修改 ~/.bashrc 文件即可。

但是在 Ubuntu 中,我需要注释掉停止处理 ~/.bashrc 的那一行:

If not running interactively, don't do anything
[ -z "$PS1" ] && return

我更喜欢检查 $- 的交互性:[ $- == *i* ]] && myalias 只会在交互式 shell 中调用 myalias。 - Quantum7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接