Часть руководства Bash, которую вы процитировали, говорит о
Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read.
Таким образом, псевдонимы на самом деле являются одним из тех примеров, которые показывают разницу между чтением и выполнением строки!
Чтобы пояснить, вот составная команда. Сначала мы пытаемся определить псевдоним, а затем пытаемся его использовать :
.alias echo=uname; echo
Кто-то, кто не знаком с Bash, может ожидать, что вывод этой команды будетLinux
(или любой другой ОС, которую вы используете ), но на самом деле она просто ничего не выводит. Это связано с тем, что Bash сначала читает строку и применяет определения псевдонимов. Вот что видит Баш:
alias echo=uname; echo
Обратите внимание, что второй echo
не преобразуется в uname
. Это потому, что Bash еще не выполнил нашу команду alias echo=uname
, он только прочитал ее . После того, как Bash прочитал строку, он выполняет то, что прочитал. Поэтому он выполняет:
alias echo=uname; echo
(это именно то, что он читал, как описано выше)
Мы даже можем проверить, выполнил ли Bash команду, набрав echo
. Поскольку ранее мы определили псевдоним, echo
теперь будет преобразовано в uname
во время шага чтения, поэтому Bash выполнит uname
.
$ alias echo=uname; echo
$ echo
Linux
После редактирования вы спросили, есть ли способ отобразить результаты после того, как Bash прочитает одну строку ввода, но до их фактического выполнения. Ответ - да,но это не очень удобно для -повседневного использования (однако, безусловно, полезно для понимания того, что происходит внутри оболочки ).
Создайте файл со следующим содержимым:
#!/bin/bash
shopt -s expand_aliases
trapped() {
echo "On line ${1}, Bash sees: $BASH_COMMAND"
}
trap 'trapped ${LINENO}' DEBUG
alias echo=uname; echo
echo
Затем запустите этот файл.
Вот объяснение того, как работает этот скрипт:
shopt -s expand_aliases
указывает Bash расширять псевдонимы, даже если он находится в неинтерактивном режиме (, как в этом случае)trapped()
. При вызове эта функция напечатает выполняемую в данный момент команду (вместе с номером строки, который передается как параметр ). trap 'trapped ${LINENO}' DEBUG
. Это сообщает Bash: «Всякий раз, когда вы видите сигнал с именем DEBUG
, сначала выполните trapped ${LINENO}
. DEBUG
— это сигнал, автоматически генерируемый Bash перед любым выполнением простой команды . Другими словами, перед выполнением любой команды вызывается наша функция trapped()
.trapped()
выполняется до того, как произойдет что-либо еще, поэтому Bash печатает то, что должно быть выполнено. Переменная LINENO
— это просто встроенная в Bash -, которая дает нам текущий номер строки. Если вы хотите иметь возможность «запускать» команды, вообще не выполняя их, и по-прежнему видеть, что читает Bash, вы можете изучить параметр extdebug
в руководстве Bash.