Alias ​​y funciones

17

Del manual de bash

Las reglas relativas a la definición y uso de alias son algo confusas. Bash siempre lee al menos una línea completa de entrada antes de ejecutar cualquiera de los comandos en esa línea. Los alias se expanden cuando se lee un comando, no cuando se ejecuta. Por lo tanto, una definición de alias que aparece en la misma línea que otro comando no tiene efecto hasta que se lea la siguiente línea de entrada. Los comandos que siguen a la definición de alias en esa línea no se ven afectados por el nuevo alias. Este comportamiento también es un problema cuando se ejecutan funciones. Los alias se expanden cuando se lee una definición de función, no cuando se ejecuta la función , porque una definición de función es en sí misma un comando compuesto. Como consecuencia, los alias definidos en una función no están disponibles hasta después de que se ejecuta esa función . Para estar seguro, siempre coloque las definiciones de alias en una línea separada y no use alias en comandos compuestos.

Las dos oraciones "Los alias se expanden cuando se lee una definición de función, no cuando se ejecuta la función" y "los alias definidos en una función no están disponibles hasta después de que se ejecuta esa función" parecen ser opuestos entre sí.

¿Puedes explicar lo que significan respectivamente?

StackExchange para todos
fuente
¡Buena pregunta! Aprendí algo nuevo hoy. Aprendí 2 cosas, en realidad: 1) esta información sobre la expansión de alias en el momento en que se lee la función def, y 2) que realmente debería leer el manual de bash con cuidado (que pensé que ya lo hice, pero aparentemente no lo hice ^^ )
Olivier Dulac
44
La pregunta principal es, ¿alguien debería usar alias en modo no interactivo? Para eso están las funciones, y los alias solo hacen que las secuencias de comandos sean más propensas a errores. En realidad, nunca he necesitado la información anterior, porque solo he encontrado alias en los .bashrcarchivos en la parte superior.
orion

Respuestas:

29
  1. Los alias se expanden cuando se lee una definición de función, no cuando se ejecuta la función ...

    $ echo "El rápido zorro marrón salta sobre el perro perezoso". > myfile
     
    $ alias myalias = gato
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    El rápido zorro marrón salta sobre el perro perezoso.
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 myusername mygroup 45 dic 13 07:07 myfile
     
    $ myfunc
    El rápido zorro marrón salta sobre el perro perezoso.

    A pesar de que myfuncse definió para llamar myalias, y lo he redefinido myalias, myfuncaún se ejecuta la definición original de myalias. Porque el alias se expandió cuando se definió la función. De hecho, el shell ya no recuerda esas myfuncllamadas myalias; solo sabe que myfuncllama cat:

    $ type myfunc
    myfunc es una función
    myfunc ()
    {
    gato myfile
    }
  2. ... los alias definidos en una función no están disponibles hasta que se ejecuta esa función.

    $ echo "El rápido zorro marrón salta sobre el perro perezoso". > myfile
     
    $ myfunc () {
    > alias myalias = gato
    >}
     
    $ myalias myfile
    -bash: myalias: comando no encontrado
     
    $ myfunc
     
    $ myalias myfile
    El rápido zorro marrón salta sobre el perro perezoso.

    El myaliasalias no está disponible hasta myfuncque se haya ejecutado la función. (Creo que sería bastante extraño si la definición de la función que define el alias fuera suficiente para causar la definición del alias).

G-Man dice 'restablecer a Mónica'
fuente
44
+1, buena respuesta. Un "corolario" importante para esto es que si uno tiene la intención de definir funciones y alias en un script, ¡mejor coloque la definición de alias antes que las definiciones de funciones! (Obvio, ahora, dada la respuesta, pero no sabía esto).
Olivier Dulac
Gracias. Creo que un problema subyacente es la diferencia entre ejecutar la definición de una función y llamar a una función. Específicamente, ¿qué operaciones de shell se realizan durante la ejecución de la definición de una función y durante la invocación de la función, respectivamente? ¿Hay alguna operación de shell que se realice tanto al ejecutar la definición de una función como al llamar a la función, o al ejecutar la definición de una función y al llamar a la función se realiza un conjunto no superpuesto de operaciones de shell?
StackExchange for All
Bueno, es un poco como la diferencia entre construir un automóvil y conducir un automóvil. O comprar un sándwich y comer un sándwich. He proporcionado una respuesta más detallada a su otra pregunta .
G-Man dice 'Reincorporar a Monica' el
Gracias. Después de volver a leer la cita del manual de bash y su respuesta, estoy confundido sobre el significado de ejecutar una función. ¿Significa ejecutar la definición de una función o llamar a una función? Ver unix.stackexchange.com/q/384209/674
StackExchange for All
1

Necesito la respuesta que se indica en la primera oración cuando intento debajo del fragmento en mi.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

después unalias -a; source ~/.bashrc, trato de ejecutar lfy lsf,

$ 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* ...

Parece claro que los alias se expanden en la definición de la función, no en la ejecución de la función, ya que :

  • cuando ejecuto lf, el error -bash: ll: command not foundy
  • cuando ejecuto lsf, /usr/bin/lsse usa, no la forma de alias, sin resaltado de color y sin caracteres de control después del archivo ejecutable.
qeatzy
fuente