Alias ​​i funkcje

17

Z podręcznika bash

Zasady dotyczące definiowania i używania aliasów są nieco mylące. Bash zawsze czyta co najmniej jeden pełny wiersz danych wejściowych przed wykonaniem dowolnego polecenia w tym wierszu. Aliasy są rozszerzane po odczytaniu polecenia, a nie podczas jego wykonywania. Dlatego definicja aliasu pojawiająca się w tym samym wierszu, co inne polecenie, nie obowiązuje, dopóki nie zostanie odczytany następny wiersz danych wejściowych. Nowy alias nie wpływa na polecenia następujące po definicji aliasu w tym wierszu. To zachowanie jest również problemem podczas wykonywania funkcji. Aliasy są rozszerzane, gdy odczytywana jest definicja funkcji, a nie podczas wykonywania funkcji , ponieważ sama definicja funkcji jest poleceniem złożonym. W konsekwencji, aliasy zdefiniowane w funkcji są dostępne dopiero po wykonaniu tej funkcji . Dla bezpieczeństwa zawsze umieszczaj definicje aliasów w osobnym wierszu i nie używaj aliasu w poleceniach złożonych.

Dwa zdania „Aliasy są rozszerzane, gdy odczytywana jest definicja funkcji, a nie podczas wykonywania funkcji” oraz „Aliasy zdefiniowane w funkcji są dostępne dopiero po wykonaniu tej funkcji” wydają się być sobie przeciwne.

Czy potrafisz wyjaśnić, co one oznaczają?

Tim
źródło
Dobre pytanie! Oparłem dziś coś nowego. Nauczyłem się 2 rzeczy, właściwie: 1) tej informacji o rozszerzeniu aliasu w czasie, gdy czytana jest funkcja def, i 2) że naprawdę powinienem dokładnie przeczytać instrukcję bash (co myślałem, że już to zrobiłem, ale najwyraźniej nie ^^ )
Olivier Dulac,
4
Główne pytanie brzmi: czy ktokolwiek powinien używać aliasów w trybie nieinteraktywnym? Do tego służą funkcje, a aliasy sprawiają, że skrypty są bardziej podatne na błędy. Tak naprawdę nigdy nie potrzebowałem powyższych informacji, ponieważ kiedykolwiek spotkałem aliasy w .bashrcplikach na samej górze.
orion,

Odpowiedzi:

29
  1. Aliasy są rozszerzane po odczytaniu definicji funkcji, a nie po uruchomieniu funkcji…

    $ echo „Szybki brązowy lis przeskakuje nad leniwym psem”. > mój plik
     
    $ alias myalias = cat
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    Szybki brązowy lis przeskakuje nad leniwym psem.
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 moja nazwa użytkownika moja grupa 45 grudnia 13 07:07 mój_plik
     
    $ myfunc
    Szybki brązowy lis przeskakuje nad leniwym psem.

    Mimo że myfunczostał zdefiniowany do wywołania myalias, a ja przedefiniowałem myalias, myfuncnadal wykonuje oryginalną definicję myalias. Ponieważ alias został rozwinięty podczas definiowania funkcji. W rzeczywistości powłoka nie pamięta już myfuncwywołań myalias; wie tylko, że myfuncwzywa cat:

    $ typ myfunc
    myfunc jest funkcją
    myfunc ()
    {
    kot mój plik
    }
  2. … Aliasy zdefiniowane w funkcji są dostępne dopiero po wykonaniu tej funkcji.

    $ echo „Szybki brązowy lis przeskakuje nad leniwym psem”. > mój plik
     
    $ myfunc () {
    > alias myalias = cat
    >}
     
    $ myalias myfile
    -bash: myalias: nie znaleziono polecenia
     
    $ myfunc
     
    $ myalias myfile
    Szybki brązowy lis przeskakuje nad leniwym psem.

    myaliasAlias nie jest dostępna aż myfuncfunkcja została wykonana. (Wydaje mi się, że byłoby dość dziwne, gdyby zdefiniowanie funkcji definiującej alias wystarczyło do zdefiniowania aliasu).

G-Man mówi „Przywróć Monikę”
źródło
4
+1, dobra odpowiedź. Ważnym „następstwem” tego jest to, że jeśli ktoś chce zdefiniować funkcje i aliasy w skrypcie, lepiej umieścić definicję aliasów przed definicjami funkcji! (oczywiste, teraz, biorąc pod uwagę odpowiedź, ale nie wiedziałem o tym).
Olivier Dulac,
Dzięki. Myślę, że zasadniczą kwestią jest różnica między uruchomieniem definicji funkcji a wywołaniem funkcji. W szczególności, jakie operacje powłoki wykonywane są odpowiednio podczas uruchamiania definicji funkcji i podczas wywoływania funkcji? Czy są jakieś operacje powłoki, które są wykonywane zarówno podczas uruchamiania definicji funkcji, jak i wywoływania funkcji, czy też uruchamianie definicji funkcji i wywoływanie funkcji wykonuje nie nakładający się zestaw operacji powłoki?
Tim
Cóż, to trochę przypomina różnicę między budowaniem samochodu a prowadzeniem samochodu. Lub kupując kanapkę i jedząc kanapkę. Podałem bardziej szczegółową odpowiedź na inne pytanie .
G-Man mówi „Przywróć Monikę”
Dzięki. Po ponownym przeczytaniu cytatu z podręcznika bash i twojej odpowiedzi jestem zdezorientowany co do znaczenia wykonywania funkcji. Czy oznacza to wykonanie definicji funkcji lub wywołanie funkcji? Zobacz unix.stackexchange.com/q/384209/674
Tim
1

Potrzebuję odpowiedzi, która jest podana w pierwszym zdaniu, gdy próbuję poniżej fragmentu kodu w moim.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

po unalias -a; source ~/.bashrc, próbuję wykonać lfi 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* ...

wydaje się wyraźnie, że aliasy są rozszerzane przy definicji funkcji, a nie przy wykonywaniu funkcji, ponieważ :

  • kiedy wykonuję lf, błąd -bash: ll: command not foundi
  • kiedy wykonuję lsf, /usr/bin/lsjest używana, nie forma aliasu, brak podświetlenia koloru i brak znaków kontrolnych po pliku wykonywalnym.
qeatzy
źródło