别名和功能


17

从bash手册

有关别名的定义和使用的规则有些混乱。在执行该行中的任何命令之前,Bash总是读取至少一行完整的输入。读取命令时将扩展别名,而不是在执行时将别名扩展。因此,与另一条命令在同一行上出现的别名定义在读取下一行输入之前不会生效。该行中别名定义之后的命令不受新别名的影响。执行功能时,此行为也是一个问题。 读取函数定义时会扩展别名,而不是在执行函数时会扩展别名,因为函数定义本身就是复合命令。作为结果, 在函数中定义的别名只有在执行该函数之后才可用。为安全起见,请始终将别名定义放在单独的行上,并且不要在复合命令中使用别名。

似乎两个句子“在读取函数定义时展开别名,而不是在执行函数时展开”和“在函数执行之后才可用的函数中定义的别名”似乎是相反的。

您能分别解释它们的意思吗?


好问题!我今天学了新东西。我实际上学到了两件事:1)在读取函数def时有关别名扩展的信息,以及2)我应该真正认真阅读bash手册(我以为我已经做过,但显然没有^^ )
Olivier Dulac

4
主要问题是,任何人都应该在非交互模式下使用别名吗?这就是函数的作用,而别名只会使脚本编写更容易出错。实际上,我从来不需要上面的信息,因为我只.bashrc在最顶层的文件中遇到过别名。
Orion

Answers:


29
  1. 读取函数定义时会扩展别名,而不是在执行函数时…

    $ echo“快速的棕色狐狸跳过了那只懒狗。” > myfile
     
    $ alias myalias =猫
     
    $ myfunc(){
    > myalias myfile
    >}
     
    $ myfunc
    敏捷的棕色狐狸跳过了懒狗。
     
    $ alias myalias =“ ls -l”
     
    $ myalias myfile
    -rw-r--r-- 1 myusername mygroup 45 12月13日07:07 myfile
     
    $ myfunc
    敏捷的棕色狐狸跳过了懒狗。

    即使myfunc已定义要调用myalias,并且已经重新定义myaliasmyfunc仍会执行的原始定义myalias。因为在定义函数时别名已扩展。实际上,shell不再记住该myfunc调用myalias;它只知道myfunc调用cat

    $类型myfunc
    myfunc是一个函数
    myfunc()
    {
    猫myfile
    }
  2. …在函数中定义的别名直到该函数执行后才可用。

    $ echo“快速的棕色狐狸跳过了那只懒狗。” > myfile
     
    $ myfunc(){
    >别名myalias = cat
    >}
     
    $ myalias myfile
    -bash:myalias:找不到命令
     
    $ myfunc
     
    $ myalias myfile
    敏捷的棕色狐狸跳过了懒狗。

    myalias直到别名是不可用myfunc的功能已被执行。(我认为,如果定义定义别名的函数足以导致定义别名,那会很奇怪。)


4
+1,很好的答案。一个重要的“推论”是,如果要在脚本中定义函数和别名,最好将别名定义放在函数定义之前!(很明显,现在已经给出了答案,但是我不知道这一点)。
奥利维尔·杜拉克

谢谢。我认为基本问题是运行函数定义和调用函数之间的区别。具体来说,在运行函数定义期间和调用函数期间分别执行哪些shell操作?在运行函数定义和调用函数的过程中,是否都执行过任何Shell操作?或者运行函数定义和调用函数的过程是否执行了不重叠的Shell操作集?
所有StackExchange

好吧,这有点像制造汽车和驾驶汽车之间的区别。或者买一个三明治,然后吃一个三明治。我为您的其他问题提供了更详细的答案。
G-Man说'Resstate Monica''8

谢谢。在重新阅读了bash手册中的引用和您的答复之后,我对执行函数的含义感到困惑。这是否意味着执行功能定义或调用功能?参见unix.stackexchange.com/q/384209/674
,所有

1

当我尝试以下代码段中的内容时,我需要第一句话给出的答案.bashrc

alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
    local CMD=${1:-ls} DIR=${2:-.};
    $CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; }     # list all file, no directories

之后unalias -a; source ~/.bashrc,我尝试执行lflsf

$ lf
-bash: ll: command not found

$ lsf
./file1 ./file2 ./script.sh ...     # no color, no control-chars

$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...

显然,别名是在函数定义而不是函数执行时扩展的,因为

  • 当我执行时lf,错误-bash: ll: command not found
  • 当我执行时lsf/usr/bin/ls使用的不是别名格式,没有颜色突出显示,并且在可执行文件后没有控制字符。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.