Есть ли в Bash и Zsh режим, позволяющий вывести на экран то, во что расширяется псевдоним при нажатии Enter?

Есть ли в Bash и Zsh режим, позволяющий вывести на экран то, во что расширяется псевдоним при нажатии Enter?

Например, если у меня есть

alias dbmigrate='rails db:migrate'

есть ли режим или простой способ настройки в Bash и Zsh так, чтобы при вводе в оболочке:

$ dbmigrate  # press Enter

он отобразит то, во что расширяется псевдоним перед его запуском?

решение1

ВБаш, есть функции alias-expand-lineи history-and-alias-expand-linereadline, но они не привязаны ни к одной клавише по умолчанию. Вы можете привязать их самостоятельно — например, с помощью Control-T:

bind '"\C-T": history-and-alias-expand-line'

Попытка связать Enterсебя будет запутанной, поскольку не каждый раз, когда вы нажимаете , Enterкоманда выполняется (например, когда это неполный конвейер и т. д.).

Есть еще одна DEBUGловушка, но определить, была ли команда действительно введена пользователем (например, не запущена из PROMPT_COMMANDили из подстановки команды в PS1), и была ли она расширена псевдонимом, будет сложно; но если вас это устраивает, распечатайтелюбойкоманда перед выполнением:

trap 'echo "> $BASH_COMMAND"' DEBUG

bash$ pwd
> pwd

Взш, вы можете просто определить preexecфункцию, которая выводит развернутую команду, если она отличается от введенной пользователем:

preexec(){ [ $1 != $2 ] && print -r "> $2" }

zsh$ j
> jobs

Однако будьте осторожны, так как некоторые трюки с псевдонимом и историей не будут работать должным образом, если вы принудительно расширите псевдоним. Например, у меня есть псевдоним cв bash для выполнения вычислений типа c 3.17 * 4.2, без необходимости экранирования *, (, и т. д.:

alias c='_c=$(fc -nl -0); bc -l <<<${_c#*c} #'

После того, как readline расширит его, текущей строкой из истории (возвращенной fc -nl -0) будетрасширенный, а не оригинальная команда, и все развалится.

решение2

Псевдонимы — это просто простые замены. Если вы хотите сделать что-то более замысловатое, например, вывести сообщение перед выполнением команды, вам нужно что-то более мощное: функция. Если вы хотите, чтобы определение выглядело как определение псевдонима, вы можете определить функцию, которая определяет функцию.

function verbose_alias {
  local name=${1%%=*} expansion=${1#*=}
  eval "function $name {
    printf >&2 '%s is an alias for %s\\n' \"$name\" \"$expansion\";
    $expansion \"\$@\";
  }"
}
verbose_alias dbmigrate='rails db:migrate'

решение3

POSIX требуетsetкомандаиметь эту возможность

-x

   Оболочка должна записывать в стандартный поток ошибок трассировку для каждой команды после ее развертывания и до ее выполнения. Не указано, трассируется ли команда, отключающая трассировку.

https://pubs.opengroup.org/onlinepubs/009604499/utilities/set.html

Так что вы можете просто использовать set -xили set -o xtraceна любых совместимых оболочках. В bash вы можете увидеть это на странице руководства:

-x

   После раскрытия каждой простой команды (for command, case command, select command или arithmetic for command) отобразите развернутое значение PS4, за которым следует команда и ее развернутые аргументы или связанный список слов.

xtrace

   Такой же как -x.

https://linux.die.net/man/1/bash

zsh также имеет подобную опцию дляsetвстроенный

XTRACE( -x, кш: -x)

   Выводить команды и их аргументы по мере их выполнения.

https://linux.die.net/man/1/zshoptions

Вы также можете указать -xопцию при выполнении скриптов или команд.

bash -x -c "echo This will be printed before running; ll"
bash -x script-to-be-debugged.sh
zsh -x -c "...; 3; md did-you-see-the-aliases"
zsh -x buggy-script.sh

Имейте в виду, что он также расширяет команды, которые выполняются до и после каждого приглашения, поэтому это может быть нежелательно во многих ситуациях, например, когда вы используете gitпеременные в PS1. В моей чистой Ubuntu VM выводится только запущенная команда

Смотрите такжеЧто делает set -x?

Другой вариант — set -vили set -o verbose, который не расширяет переменные перед печатью.

решение4

По умолчанию в bash такая помощь недоступна.

Две связанные функции, доступные по умолчанию:

  • shopt -s histverify

Если установлено и используется readline, результаты подстановки истории не передаются немедленно в парсер оболочки. Вместо этого результирующая строка загружается в буфер редактирования readline, что позволяет вносить дальнейшие изменения.

Который решает часть действия при Enterнажатии, но только с расширением истории в командной строке. Например:

$ shopt -s histverify
$ echo "this is a test"
This is a test
$ echo !!
$ echo echo "this is a test"  <---- expanded by the simple use of enter!! 
  • Читаемая строкаshell-expand-line

линия расширения оболочки (MCe)

Расширьте строку, как это делает оболочка. Это выполняет расширение псевдонима и истории, а также все расширения слов оболочки. См. РАСШИРЕНИЕ ИСТОРИИ ниже для описания расширения истории.

Это именно то, что вы просите сделать, но ключ к тому, чтобы это сработало , CtrlAlte

Извините , я не знаю решения, которое работает с вводом и выполняет shell-expand-line.

Связанный контент