~/.bashrc
文件中包含两个定义:commandA
,它是较长路径的别名。 Bash脚本我想用这两个命令处理同一文件,所以我编写了以下Bash脚本:
#!/bin/bash
for file in "$@"
do
commandA $file
commandB $file
done
即使注销了会话并重新登录后,运行该脚本时,Bash也会提示我两个命令均出现
commandB
错误。我在做什么错?
#1 楼
首先,正如ddeimeke所说,默认情况下,别名不会在非交互式shell中扩展。其次,除非您设置
.bashrc
环境变量,否则非交互式shell不会读取BASH_ENV
。 > 但最重要的是:不要那样做!请?有一天,您将把该脚本移到未设置必要别名的地方,它将再次中断。
在脚本中设置并使用变量作为快捷方式:
#!/bin/bash
CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh
for file in "$@"
do
$CMDA "$file"
$CMDB "$file"
done
评论
该解决方案不适用于通常的别名用例。例如。别名mv =“ mv -v --backup = numbered”。
– Evi1M4chine
16年4月23日在20:11
@ Evi1M4chine:是的。至少在我还原了Gilles不必要的编辑之后。但是无论如何,最好对参数使用不同的变量。
–user601
16年4月24日在15:50
嗯,请注意$ CMDA / $ CMDB周围缺少引号...除了在bash中为bash本身保留大写变量,而且确实有效之外,缺少引号让我真的很不舒服...还是谢谢。
– Evi1M4chine
16年4月30日在0:26
@ Evi1M4chine:嗯,什么? 1.我本人在最近的编辑中删除了引号。 2.您从何处获得“保留给bash本身”?这将是我第一次听说。 3.如果这让您感到不安,那么首先感觉如何使用bash?无论如何,请按照我告诉您的方式为选项使用单独的变量。
–user601
16年4月30日在17:46
@alvas:假定gizmo不在路径上,或者存在具有相同名称但具有更高优先级的命令。否则,您可以首先简单地将CMDA设置为纯Gizmo。
–user601
17-4-5在9:20
#2 楼
如果查看bash联机帮助页,则会发现:如果交互式交互式
shell不扩展别名,除非设置了
expand_aliases shell选项
使用shopt(请参阅下面的SHELL BUILTIN COMMANDS下的
shopt的说明
)。 br />
在脚本中。
在脚本中设置别名后,请确保提供别名文件。
shopt -s expand_aliases
评论
我将其放在脚本中,但仍无法正常工作。同样的错误。
– Zaid
2010-09-2 10:29
添加shopt -s expand_aliases源〜/ .bash_aliases非常适合我。通常,.bashrc中有一种交互式外壳程序检测形式,如下所示:#如果未以交互方式运行,则不执行任何操作[-z“ $ PS1”] &&返回@Zaid,也许您想检查文件中的内容即可。来源。
–弗兰克·舒伯特(Frank Schubert)
13年4月4日在1:46
优秀的!保存了我的脚本! :)很难在终端上阅读/搜索/浏览信息和手册页,以至于我很久以前就放弃了,可以在互联网上搜索...
–水瓶座力量
2013年9月17日19:24在
奇怪的是,shopt -s expand_aliases不必在别名定义之前,而在使用别名之前。添加到@FrankSchubert:交互式shell检测也可以使用$-进行,该$包含shell的选项,特别是i(如果shell是交互式的)。
–有效
15年3月20日在14:12
这不是正确的答案...在脚本中添加别名不是答案。您的〜/ .bash_aliases可能取决于先前加载在交互式shell上的其他内容...我发现的最近的东西是将您的hashbang更改为#!/ bin / bash -li仍然不完美。理想情况下,您应该使用函数而不是别名。
– Steefanos Kalantzis
16-2-5在11:47
#3 楼
别名无法导出,因此在未定义别名的Shell脚本中不可用。换句话说,如果您在~/.bashrc
中定义它们,则它们对your_script.sh
不可用(除非您在脚本中提供~/.bashrc
,我不建议这样做,但是有一些方法可以正确执行此操作)。但是,可以导出函数,这些函数可用于在定义它们的环境中运行的Shell脚本。可以通过将其放在您的bashrc中来完成:
foo() { echo "Hello World!" } export -f foo
正如Bash手册中所说:“几乎所有目的,shell函数都比别名更受青睐。” />
评论
虽然从技术上讲这还不能解决问题,但是正如您所说,您可以简单地将别名commandA = ...替换为commandA(){...},然后导出commandA,您将获得与别名相同的行为。因此,据我所知,这几乎是别名的替代选择,在bash脚本中效果很好
–菲利达
18年5月21日在18:35
这里的问题是,当您需要一个别名时,将许多引用的选项传递给它。例如,使用别名b = bash可以很容易地执行b -c“回声测试| grep测试”,而这在函数中是很难做到的。
– Fmstrat
19年8月13日在16:03
@Fmstrat:b(){bash“ $ @”;然后b -c“ echo test | grep test”
–丹尼斯·威廉姆森
19年8月13日在16:10
当需要在从另一个脚本获得功能的脚本中评估函数的内容时,这不能解决问题...
–明仁
20年1月29日在18:10
#4 楼
[cmd line] > bash -i [your script's file path]
i
用于互动,并为您提供bash
配置文件。#5 楼
您可以在脚本之前使用.
。将其运行为:. /path/to/your/scrtip.sh
您可以在bash脚本中以以下方式检查此情况:
if [[ $- == *i* ]]
then
echo "running on interactive mode. aliases will work!"
fi
#6 楼
我发现有时bash脚本也无法识别导出。但是,将其更改为#!/bin/sh
对我有用。
评论
不,不是...
–哈菲兹·特姆里(Hafiz Temuri)
18年4月22日在17:12
评论
顺便说一句,无需登录和注销即可识别别名。您只需要执行源〜/ .bashrc。就我而言,我在关闭SSH代理并再次连接后开始添加别名后,通过SSH代理远程连接。
别名是一种缩短命令的方法。 (它们仅在交互式外壳中使用,而不在脚本中使用-这是脚本和交互式外壳之间的极少数差异之一。)