使用bash one liner创建别名

时间:2016-08-08 15:15:15

标签: linux bash unix

我需要为我的长命令创建别名,通常我会使用

alias myLongCommand="my long command"

但是我需要在在线系统配置中定义我只能使用bash命令,我尝试了各种组合,包括:

bash -c 'alias myLongCommand="my long command"'

但遗憾的是没有成功,别名没有定义。

为了测试成功,我使用

bash -c myLongCommand

2 个答案:

答案 0 :(得分:4)

简答:使用导出的函数

# define a function
myLongCommand() { my long command; }

# export that function to the environment
export -f myLongCommand

# thereafter, that function is available in subprocesses
bash -c 'myLongCommand'

...或者,将实际创作压缩为单行:

myLongCommand() { my long command; }; export -f myLongCommand

请注意,定义和导出需要在bash shell中完成,bash shell本身就是shell的父进程,您希望在其中使用该函数。如果使用bash -c 'myLongCommand() { my long command; }; export -f myLongCommand',则导出函数的环境变量仅与bash -c实例一样长 - 因此,它在任何后续命令中都完全不可用。

如果您希望登录会话中的所有bash shell都可以使用它,那么您可以将定义和导出放在~/.bash_profile中(并注销并重新登录),如果您的系统按照典型的默认值运行关于dotfile初始化。

更长的回答:为什么原始尝试会失败?

多种原因:

  • 别名是单个shell进程状态的一部分 - 没有共享注册表。因此,bash -c 'alias foo="bar"'仅为bash -c命令创建的单个bash实例设置别名,并在该命令退出时终止该别名。
  • 非交互式shell(例如使用bash -c创建的shell)不会从其父进程继承别名,读取dotfiles(默认情况下),因此它们从别名表开始即使在调用它们的(单独)shell中定义了别名,也为空。
  • 非交互式shell(例如使用bash -c创建的shell)默认情况下已关闭别名评估,因为这是一个交互式使用功能。

更长的答案:为什么不是别名?

别名旨在作为交互式使用的工具。因此,默认情况下它们根本不在非交互式弹壳内。要在非交互式bash实例中启用别名扩展,需要运行:

shopt -s expand_aliases

另一个问题实际上是在所有中定义了别名。非交互式shell默认情况下不运行dotfiles(在非交互式shell中运行的dotfile的名称可以放在ENVBASH_ENV环境变量中以覆盖它),因此它们不会有在~/.bashrc中定义的别名。

更长的答案:......那么, 你如何使用别名?

# create a .env file, taking care not to fail badly if shell is not bash
# note that making noninteractive shells emit content on stderr will break some software
# ...so redirecting errors is entirely essential here, and ||: is necessary to not break
# ...any noninteractive shell (like dash or ash invocations) that doesn't support shopt
# ...when that shell is invoked with the -e argument.
cat >~/.env <<'EOF'
shopt -s expand_aliases 2>/dev/null ||: "fail gracefully w/o shopt"
alias myLongCommand="my long command" 2>/dev/null ||: "fail gracefully w/o aliases"
EOF

# point to it from your .bash_profile
cat >>~/.bash_profile <<'EOF'
export ENV=$HOME/.env
[[ -e $ENV ]] && source "$ENV"
EOF

# ...and update the already-running shell:
export ENV=$HOME/.env
source "$ENV"

...在一行中完成上述操作:

printf '%s\n' 'shopt -s expand_aliases 2>/dev/null ||:' 'alias myLongCommand="my long command" 2>/dev/null ||:' >~/.env; printf '%s\n' 'export ENV=$HOME/.env' '[[ -e $ENV ]] && source "$ENV"' >>~/.bash_profile

答案 1 :(得分:2)

bash -c会生成bash的非登录非交互式实例,它不会读取任何会话启动配置文件(与登录/交互式会话不同),因此没有alias定义可用且仅在命令(在这种情况下为alias myLongCommand="my long command")退出时退出。所以大概你不会得到别名。

要永久设置别名,您应该使用shell在启动会话时读取的任何文件,对于交互式会话,bash读取~/.bashrc。因此,如果您将alias定义放在那里,它将在任何交互式bash实例上提供:

echo 'alias myLongCommand="my long command"' >> ~/.bashrc

使其可用;能够从正在运行的会话中source文件:

source ~/.bashrc

现在,从非交互式(和非登录)会话即bash -c,您可以通过使用alias选项使shell具有交互性来使-i可用,因此{ {1}}被读取:

~/.bashrc