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


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.