Например, если у меня есть
alias dbmigrate='rails db:migrate'
есть ли режим или простой способ настройки в Bash и Zsh так, чтобы при вводе в оболочке:
$ dbmigrate # press Enter
он отобразит то, во что расширяется псевдоним перед его запуском?
решение1
ВБаш, есть функции alias-expand-line
и history-and-alias-expand-line
readline, но они не привязаны ни к одной клавише по умолчанию. Вы можете привязать их самостоятельно — например, с помощью 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
.
zsh также имеет подобную опцию дляset
встроенный
XTRACE(
-x
, кш:-x
)Выводить команды и их аргументы по мере их выполнения.
Вы также можете указать -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)
Расширьте строку, как это делает оболочка. Это выполняет расширение псевдонима и истории, а также все расширения слов оболочки. См. РАСШИРЕНИЕ ИСТОРИИ ниже для описания расширения истории.
Это именно то, что вы просите сделать, но ключ к тому, чтобы это сработало , Ctrl—Alte
Извините , я не знаю решения, которое работает с вводом и выполняет shell-expand-line
.