显示带有替换的别名

显示带有替换的别名

有没有办法显示别名bash 已经进行了替换吗?

背景:
我有一个很长的别名,可以对目录执行操作。

alias do_it='cd my_working_dir; do_stuff'

这工作正常,但别名很长并且my_working_dir经常更改。我没有对我的别名进行深入搜索以查找所有出现的my_working_dir,而是更改为:

MY_WORKING_DIR=some_dir
alias do_it='cd ${MY_WORKING_DIR}; do_stuff'

这很好用。

但是,有时我想即时对别名进行一些细微的更改。通过之前的别名构造,我能够输入alias、复制/粘贴我想要的命令、制作 mods 并执行。使用这种替换,当我输入时alias我得到:

do_it='cd ${MY_WORKING_DIR}; do_stuff'

现在我必须手动替换MY_WORKING_DIR.有没有一种方便的方法来获取别名的副本bash 已进行替换(在本例中替换为${MY_WORKING_DIR}.

澄清:我的目标不是更改别名/函数的输入。我希望显示生成的别名/函数已经进行替换这样我就可以复制/粘贴该输出以创建更复杂的命令。我还没有找到一种方法来显示别名或已进行替换的函数。

附加示例

TARGET_DIR='my_dir'    
alias do_it='cd ${TARGET_DIR}; run task; echo "Task done in ${TARGET_DIR}'
alias
do_it='cd ${TARGET_DIR}; run task; echo "Task done in ${TARGET_DIR}'

如果我想重复别名 50x,我可以复制别名输出,然后将其粘贴到以下行中:

for i in {1..50}; do <paste_here>; done

但这是行不通的,因为alias输出导致 ${TARGET_DIR} 未解析。

使用函数代替别名也不起作用,因为declare同样不能替换 ${TARGET_DIR}。

这是一个简化的示例。我使用的真正别名又长又乏味, ${TARGET_DIR} 出现了很多次,因此虽然别名/函数效果很好,但将别名输出组合成更复杂的即时命令需要我手动替换 ${TARGET_DIR } 多次。

答案1

据我所知,至少不是以安全和通用的方式。对我来说,这似乎也是一种极其奇怪的使用别名的方式。

您确定 shell 脚本不会更合适吗?放在你身上的东西$PATH$PATH如果需要的话可以调整)并命名do_it东西可能需要参数。

您还可以让该脚本执行与别名相同的操作,并根据要求显示带有替换的别名命令。


如果您坚持使用别名,这是非常不安全的,因为您可能会冒着扩展超出您想要的范围、错误处理转义字符\等的风险,但您可以执行类似以下操作:

$ alias test='echo $UID'
$ alias xalias='f(){ eval echo $(echo $(alias "$@" | sed s,\'\'',\'\\\\\\\\\\\\\'',g ) ) ; unset -f f; }; f'
$ xalias test
alias test='echo 1000'

获得正确的报价是一项令人沮丧的工作。这是通过引用单引号来实现的:'-> \',然后再次引用所有内容。第一次eval调用取消对级别的引用,此时,${VAR}不再引用级别,因此对它们进行求值。然后echo添加回引号,因为字符串是在子 shell 中计算的。由于间接的数量,我可能有点过于复杂了。

这仍然很脆弱,并且 bash+sed 不适合这项工作。

答案2

由于您似乎希望每隔一段时间更改一次工作目录,因此建议将别名替换为 shell 函数,该函数可以将目录路径名作为命令行参数:

do_it () {
    local wd="${1:-my_working_dir}"
    cd "$wd" || return
    do_stuff
 }

该函数采用一个可选的单个参数,即目录路径名。如果给定,函数的局部wd变量将设置为此值。如果未给出,则将局部wd变量设置为 static string my_working_dir

通过一个小的更改,您可以禁止该函数将用户留在意外的工作目录中:

do_it () {
    local wd="${1:-my_working_dir}"
    (
        cd "$wd" || return
        do_stuff
    )
 }

函数内部带括号的子 shell 环境(包括当前工作目录,可能由 修改cd)不会影响调用 shell 的环境。

您可以在通常声明别名的地方声明此函数,并且可以将其用作

do_it

或者有一个论据,

do_it some/directory/path

或者,在对多个目录路径名运行它的循环中,

for target_dir in some/pattern/dir*/
do
    do_it "$target_dir"
done

答案3

这是以下内容的副本:

如何在 bash 中内联扩展别名?

在执行之前展开子shell?

事实证明,BASH 使用 readline 来处理这个问题。只需按Esc然后Ctrl-e

为了进行测试,我在 .bash_profile 中定义了以下别名:

alias cdh='cd ${HOME}'

启动一个新的 shell/终端允许我输入:

cdh

然后按: Esc Ctrl-e

readline 将命令行更新为:

cd /home/user_name 

MacOS 13.2.1
iterm2 3.4.15
bash 5.1.8(1)-发布 (x86_64-apple-darwin21.2.0)

Ubuntu 20.04.5 LTS
5.0.17(1)-发布 (x86_64-pc-linux-gnu)

相关内容