Псевдоніми та функції


17

З посібника з баш

Правила щодо визначення та використання псевдонімів дещо заплутані. Bash завжди читає щонайменше один повний рядок введення, перш ніж виконувати будь-яку команду в цьому рядку. Псевдоніми розгортаються, коли команда читається, а не коли вона виконується. Тому визначення псевдоніму, що з’являється в тому ж рядку, що й інша команда, не набирає чинності, поки не буде прочитаний наступний рядок введення. Команди, що відповідають визначенню псевдоніму в цьому рядку, не впливають на новий псевдонім. Така поведінка також є проблемою при виконанні функцій. Псевдоніми розширюються при зчитуванні визначення функції, а не при виконанні функції , оскільки визначення функції саме по собі є складною командою. Як наслідок, псевдоніми, визначені у функції, доступні лише після того, як ця функція буде виконана . Щоб бути безпечним, завжди ставте визначення псевдонімів в окремий рядок і не використовуйте псевдоніми у складених командах.

Два речення "Псевдоніми розширюються, коли читається визначення функції, а не тоді, коли функція виконується" та "Псевдоніми, визначені у функції, недоступні, поки після виконання цієї функції" здаються суперечать один одному.

Чи можете ви пояснити, що вони означають відповідно?


Гарне питання! Я сьогодні схилився до чогось нового. Я дізнався 2 речі, насправді: 1) цю інформацію про розширення псевдоніму під час читання функції def, і 2) про те, що я дійсно повинен уважно читати посібник з bash (що я думав, що вже зробив, але, мабуть, не ^^ )
Олів'є Дулак

4
Головне питання: чи повинен хтось використовувати псевдоніми в неінтерактивному режимі? Ось для чого призначені функції, і псевдоніми просто роблять сценарій більш схильним до помилок. Мені фактично ніколи не була потрібна інформація, наведена вище, тому що я зустрічався лише з псевдонімами у .bashrcфайлах у самому верху.
Оріон

Відповіді:


29
  1. Псевдоніми розширюються при зчитуванні визначення функції, а не при виконанні функції ...

    $ echo "Швидка бура лисиця перестрибує через ледачого собаку". > мій файл
     
    $ alias myalias = кіт
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    Швидка бура лисиця стрибає над ледачим собакою.
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 myusername mygroup 45 13 грудня 07:07 myfile
     
    $ myfunc
    Швидка бура лисиця стрибає над ледачим собакою.

    Незважаючи на те, що myfuncбуло визначено для виклику myalias, і я його переглянув myalias, myfuncвсе ще виконується початкове визначення myalias. Тому що псевдонім було розширено, коли була визначена функція. Насправді оболонка вже не пам’ятає про те, що myfuncвикликає myalias; він знає лише те, що myfuncдзвонить cat:

    $ type myfunc
    myfunc - це функція
    myfunc ()
    {
    myfile кішка
    }
  2. ... псевдоніми, визначені у функції, доступні лише після того, як ця функція буде виконана.

    $ echo "Швидка бура лисиця перестрибує через ледачого собаку". > мій файл
     
    $ myfunc () {
    > псевдонім myalias = кіт
    >}
     
    $ myalias myfile
    -bash: myalias: команда не знайдена
     
    $ myfunc
     
    $ myalias myfile
    Швидка бура лисиця стрибає над ледачим собакою.

    myaliasІм'я користувача не доступний , поки myfuncфункції не буде виконана. (Я вважаю, що це було б досить дивно, якби визначення функції, яка визначає псевдонім, було достатньо, щоб викликати псевдонім.)


4
+1, хороша відповідь. Важливим "наслідком" для цього є те, що якщо хтось має намір визначити функції та псевдоніми в сценарії, краще поставте визначення псевдонімів перед визначеннями функцій! (очевидно, зараз, давши відповідь, але я цього не знав).
Олів'є Дулак

Спасибі. Я думаю, що основна проблема полягає в різниці між виконанням визначення функції та викликом функції. Зокрема, які операції з оболонкою виконуються під час виконання визначення функції та під час виклику функції відповідно? Чи є якісь операції з оболонками, які виконуються під час виконання визначення функції та виклику функції, або виконують визначення функції та виклику функції виконують набір операцій оболонки, що не перекривається?
Тім

Ну, це трохи схоже на різницю між побудовою автомобіля та керуванням автомобілем. Або купити бутерброд і поїсти бутерброд. Я надав більш детальну відповідь на ваше інше питання .
G-Man каже: "Відновіть Моніку"

Спасибі. Перечитавши цитату з посібника по 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, я намагаюся виконати lfі 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* ...

очевидно, що псевдоніми розширюються на визначення функції, а не на виконання функції, оскільки :

  • коли я виконую lf, помилка -bash: ll: command not foundта
  • коли я виконую lsf, /usr/bin/lsвикористовується не псевдонім форма, ні виділення кольорів, ні контрольні символи після виконуваного файлу.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.