Alias ​​e funzioni


17

Dal manuale di bash

Le regole relative alla definizione e all'uso degli alias sono alquanto confuse. Bash legge sempre almeno una riga di input completa prima di eseguire qualsiasi comando su quella riga. Gli alias vengono espansi quando viene letto un comando, non quando viene eseguito. Pertanto, una definizione di alias che appare sulla stessa riga di un altro comando non ha effetto fino a quando non viene letta la riga successiva di input. I comandi che seguono la definizione di alias su quella riga non sono interessati dal nuovo alias. Questo comportamento è anche un problema quando vengono eseguite le funzioni. Gli alias vengono espansi quando viene letta una definizione di funzione, non quando viene eseguita la funzione , poiché una definizione di funzione è essa stessa un comando composto. Come conseguenza, gli alias definiti in una funzione non sono disponibili fino a quando non viene eseguita quella funzione . Per sicurezza, posiziona sempre le definizioni di alias su una riga separata e non utilizzare l'alias nei comandi composti.

Le due frasi "Gli alias vengono espansi quando viene letta una definizione di funzione, non quando viene eseguita la funzione" e "gli alias definiti in una funzione non sono disponibili fino a quando non viene eseguita quella funzione" sembrano essere in contrasto tra loro.

Puoi spiegare cosa significano rispettivamente?


Buona domanda! Oggi ho appoggiato qualcosa di nuovo. Ho imparato 2 cose, in realtà: 1) queste informazioni sull'espansione dell'alias al momento della lettura della funzione def, e 2) che dovrei davvero leggere attentamente il manuale di bash (cosa che pensavo di aver già fatto, ma apparentemente non l'ho fatto ^^ )
Olivier Dulac il

4
La domanda principale è: qualcuno dovrebbe usare gli alias in modalità non interattiva? Ecco a cosa servono le funzioni e gli alias rendono gli script più soggetti a errori. In realtà non ho mai avuto bisogno delle informazioni di cui sopra, perché ho mai incontrato alias solo nei .bashrcfile nella parte superiore.
Orione,

Risposte:


29
  1. Gli alias vengono espansi quando viene letta una definizione di funzione, non quando viene eseguita la funzione ...

    $ echo "La rapida volpe marrone salta sopra il cane pigro." > myfile
     
    $ alias myalias = cat
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    La rapida volpe marrone salta sopra il cane pigro.
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 myusername mygroup 45 dic 13 07:07 myfile
     
    $ myfunc
    La rapida volpe marrone salta sopra il cane pigro.

    Anche se è myfuncstato definito per chiamare myalias, e ho ridefinito myalias, myfuncesegue ancora la definizione originale di myalias. Perché l'alias è stato espanso quando è stata definita la funzione. In effetti, la shell non ricorda più quella myfuncchiamata myalias; sa solo che myfuncchiama cat:

    $ type myfunc
    myfunc è una funzione
    myfunc ()
    {
    cat myfile
    }
  2. … Gli alias definiti in una funzione non sono disponibili fino a quando non viene eseguita quella funzione.

    $ echo "La rapida volpe marrone salta sopra il cane pigro." > myfile
     
    $ myfunc () {
    > alias myalias = cat
    >}
     
    $ myalias myfile
    -bash: myalias: comando non trovato
     
    $ myfunc
     
    $ myalias myfile
    La rapida volpe marrone salta sopra il cane pigro.

    L' myaliasalias non è disponibile fino a quando la myfuncfunzione non è stata eseguita. (Credo che sarebbe piuttosto strano se la definizione della funzione che definisce l'alias fosse sufficiente per determinare l'alias.)


4
+1, buona risposta. Un "corollario" importante di questo è che se si intende definire funzioni e alias in uno script, mettere meglio la definizione degli alias prima delle definizioni delle funzioni! (ovvio, ora, data la risposta, ma non lo sapevo).
Olivier Dulac il

Grazie. Penso che un problema di fondo sia la differenza tra eseguire la definizione di una funzione e chiamare una funzione. In particolare, quali operazioni della shell vengono eseguite durante l'esecuzione della definizione di una funzione e durante la chiamata della funzione rispettivamente? Esistono delle operazioni di shell che vengono eseguite sia durante l'esecuzione della definizione di una funzione sia chiamando la funzione, oppure eseguendo la definizione di una funzione e chiamando la funzione si eseguono un insieme di operazioni di shell non sovrapposte?
StackExchange per tutto il

Bene, è un po 'come la differenza tra la costruzione di un'auto e la guida di un'auto. O comprare un panino e mangiare un panino. Ho fornito una risposta più dettagliata alla tua altra domanda .
G-Man dice "Ripristina Monica" il

Grazie. Dopo aver riletto la citazione dal manuale di bash e la tua risposta, sono confuso sul significato dell'esecuzione di una funzione. Significa eseguire la definizione di una funzione o chiamare una funzione? Vedi unix.stackexchange.com/q/384209/674
StackExchange per tutti il

1

Ho bisogno della risposta che è indicata dalla prima frase quando provo sotto lo snippet nel mio.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

dopo unalias -a; source ~/.bashrc, provo a eseguire lfe 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* ...

sembra chiaramente che gli alias siano espansi alla definizione della funzione, non all'esecuzione della funzione, poiché :

  • quando eseguo lf, l'errore -bash: ll: command not founde
  • quando eseguo lsf, /usr/bin/lsviene utilizzato, non il modulo alias, nessun evidenziatore di colore e nessun carattere di controllo dopo il file eseguibile.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.