Псевдоним и функции

17

Из руководства по bash

Правила, касающиеся определения и использования псевдонимов, несколько сбивают с толку. Bash всегда читает по крайней мере одну полную строку ввода перед выполнением любой из команд в этой строке. Псевдонимы раскрываются при чтении команды, а не при ее выполнении. Следовательно, определение псевдонима, отображаемое в той же строке, что и другая команда, не вступает в силу, пока не будет прочитана следующая строка ввода. На команды, следующие за определением псевдонима в этой строке, новый псевдоним не влияет. Такое поведение также является проблемой при выполнении функций. Псевдонимы раскрываются при чтении определения функции, а не при ее выполнении , поскольку определение функции само по себе является составной командой. Как следствие, псевдонимы, определенные в функции, недоступны до тех пор, пока эта функция не будет выполнена . В целях безопасности всегда помещайте определения псевдонимов в отдельной строке и не используйте псевдоним в составных командах.

Два предложения «псевдонимы раскрываются при чтении определения функции, а не при выполнении функции» и «псевдонимы, определенные в функции, недоступны до тех пор, пока эта функция не будет выполнена» кажутся противоречащими друг другу.

Можете ли вы объяснить, что они имеют в виду соответственно?

StackExchange для всех
источник
Хороший вопрос! Я наклонился что-то новое сегодня. На самом деле я узнал 2 вещи: 1) эту информацию о расширении псевдонимов во время чтения функции def, и 2) что я действительно должен внимательно прочитать руководство по bash (что, как я думал, я уже сделал, но, очевидно, не сделал ^^ )
Оливье Дюлак
4
Главный вопрос: кто-нибудь должен использовать псевдонимы в неинтерактивном режиме? Это то, для чего нужны функции, а псевдонимы просто делают сценарии более подверженными ошибкам. Я на самом деле никогда не нуждался в информации выше, потому что я когда-либо встречал псевдонимы в .bashrcфайлах в самом верху.
Орион

Ответы:

29
  1. Псевдонимы раскрываются при чтении определения функции, а не при ее выполнении…

    $ echo "Быстрая коричневая лиса перепрыгивает через ленивую собаку." > мой файл
     
    $ alias myalias = cat
     
    $ myfunc () {
    > Миалиас мой файл
    >}
     
    $ 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 ()
    {
    кот мой файл
    }
  2. ... псевдонимы, определенные в функции, недоступны до тех пор, пока эта функция не будет выполнена.

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

    myaliasПсевдоним не доступен , пока myfuncфункция не будет выполнена. (Я считаю, что было бы довольно странно, если бы определения функции, определяющей псевдоним, было достаточно для определения псевдонима.)

G-Man говорит: «Восстанови Монику»
источник
4
+1, хороший ответ. Важным «следствием» этого является то, что если кто-то намеревается определить функции и псевдонимы в скрипте, лучше поместить определение псевдонимов перед определениями функций! (очевидно, сейчас, учитывая ответ, но я этого не знал).
Оливье Дюлак
Благодарю. Я думаю, что основной проблемой является разница между выполнением определения функции и вызовом функции. В частности, какие операции оболочки выполняются при выполнении определения функции и при вызове функции соответственно? Существуют ли какие-либо операции оболочки, которые выполняются как при выполнении определения функции, так и при ее вызове, или при выполнении определения функции и при вызове функции выполняется неперекрывающийся набор операций оболочки?
StackExchange для всех
Ну, это немного похоже на разницу между созданием машины и вождением машины. Или покупать бутерброд и есть бутерброд. Я предоставил более подробный ответ на ваш другой вопрос .
G-Man говорит: «Восстановите Монику»
Благодарю. Перечитав цитату из руководства по bash и ваш ответ, я не понимаю смысла выполнения функции. Означает ли это выполнение определения функции или вызов функции? См. Unix.stackexchange.com/q/384209/674
StackExchange для всех
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используется, а не форма псевдонима, отсутствие выделения цвета и контрольные символы после исполняемого файла.
qeatzy
источник