← На главную

В bash и zsh: ! подставляет прошлые команды и вытаскивает их части

06.08.2026 14:53 · hackernews

В командной строке можно не ловить стрелку вверх, а ссылаться на предыдущие команды через восклицательные знаки. Об этом рассказывает статья, нацеленная на bash, csh, tcsh и zsh.

Все event designators строятся по шаблону ![событие]:[часть]:[модификатор]. Событие выбирает команду из истории: !! — предыдущая, !ssh — последняя команда, начинающаяся с ssh, !?dandelion? — содержащая dandelion, !# — команда, набираемая прямо сейчас. Часть указывает, какие аргументы нужны: !:0 — сама команда, !:1 — первый аргумент, !$ — последний, !* — все. Модификаторы умеют вытаскивать из аргумента директорию (:h), имя файла (:t), убирать расширение (:r) или заменять подстроку (:s/foo/bar/, :gs/foo/bar/). Например, !$:h даст каталог последнего аргумента, !:1:t — имя файла от первого аргумента.

Вся эта магия — только для интерактивных шеллов, для скриптов она не предназначена. Чтобы случайно не выполнить не то, в bash есть shopt -s histverify, а в zsh — setopt HIST_VERIFY: они покажут развёрнутую команду перед запуском. Модификатор :p тоже печатает результат, не выполняя его.

Отдельно автор хвалит fc из POSIX. Просто fc открывает предыдущую команду в редакторе, который задан через $FCEDIT или $EDITOR. Можно указать диапазон: fc -3 -1, а через -e даже применить к командам sed — например, заменить продовый хост на тестовый и выполнить ту же серию действий.

Статья сравнивает event designators с ctrl-r и alt-. — поиск по истории хорош, но дизайнеры мощнее: они извлекают части команды, а не просто подставляют шаблон. Если восклицательные знаки мешают, их можно отключить: set +H в bash, setopt nobanghist в zsh. Или переназначить символы через histchars. Автор советует потренироваться и помнить: восклицательные знаки в шелле — не для крика, а для экономии клавиш.

Читать оригинал →