Как стать автором
Обновить

Комментарии 64

Спасибо за pgUp/pgDown, не знал, что можно листать ими команды.
На здоровье)

К PgUp/PgDown сильно привык, так что когда пользуюсь некоторыми дистрибутивах, в которых они отключены (не прописаны в /etc/inputrc), одно из первых действий лезу добавить их обратно в /etc/inputrc
А я всегда Alt+f/b и PgUp/PgDown меняю в .inputrc на
"\e[A":history-search-backward # up
"\e[B":history-search-forward # down
"\e[1;5C": forward-word # ctrl + right
"\e[1;5D": backward-word # ctrl + left
можно ещё набрать history — выдаст весь список ранее вводившихся команд
затем вводите восклицательный знак и номер нужной команды — она выполняется

часто в настройках шелла сразу делают для history алиас на букву h (чтобы не вводить всё слово)
У меня по Ctrl-R привязана функция с использованием команды percol — получился типа менюобразного контекстного поиска

Ущу удобно


history
!123 # потом нажимаем ctrl+alt+e и !123 раскрывается в команду которую можно редактировать
нет никакой фразы (типа «Горшочек, не вари»), которую бы команда cat восприняла как «окончание ввода»

Если хочется, то можно и так (конечно, это сама оболочка распарсит, а не cat):


cat << 'Горшочек, не вари' > helloworld.txt
Привет, мир!
И тебе привет.
Горшочек, не вари

В отличие от Ctrl+D можно использовать в скриптах.

Улыбнуло использование фразы из текста)

да, верно — есть у bash'а(не у cat) такая возможность — «Here Documents» называется (в «man bash»).

Еще можно с табами использовать (в скриптах удобно), если написать "<<-":
cat <<- 'Горшочек, не вари' > helloworld.txt
    Привет, мир!
    И тебе привет.
Горшочек, не вари
Обидно только, что многие терминалы не уважают многие хоткеи
Спасибо! Ссылку на страничку отправил в поминальник. И себе, и буду делиться с новичками.

Мне удобнее использовать Up/Down для листания истории с учётом начала команды. И Tab без учёта регистра. Поэтому всегда первым делом правлю .inputrc:


"\e[A": history-search-backward
"\e[B": history-search-forward
"\e\e": kill-whole-line

set colored-stats On
set completion-ignore-case On
set completion-prefix-display-length 3
set mark-symlinked-directories On
set show-all-if-ambiguous On
set show-all-if-unmodified On
set visible-stats On

Как без этого жить вообще?

Полезно.

Судя по «man readline»:
  • set colored-stats On — подкрашивать автодополняемые имена цветом как и ls
  • set completion-ignore-case On — тут понятно, игнорировать регистр при дополнении
  • set completion-prefix-display-length 3 — как понял, общую часть дополнения при отображении схлопывает до "___"
  • set mark-symlinked-directories On — помечает дириктории-симлинки "@" — удобно при включеной colored-stats
  • set show-all-if-ambiguous On — начинает отображать возможные автодополнения по первому Tab'у
  • set show-all-if-unmodified On — не понял отличие от предыдущего параметра
  • set visible-stats On — должно(у меня не сработало) отображать информацию о файлах в автодополнении

Я так давно читал man readline и задавал эти опции, что уже и сам забыл, что некоторые из них значат. Спасибо, что не поленились сделать summary. Хоть перечитал.


show-all-if-ambiguous
This alters the default behavior of the completion functions. If set to ‘on’, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. The default value is ‘off’.

show-all-if-unmodified
This alters the default behavior of the completion functions in a fashion similar to show-all-if-ambiguous. If set to ‘on’, words which have more than one possible completion without any possible partial completion (the possible completions don’t share a common prefix) cause the matches to be listed immediately instead of ringing the bell. The default value is ‘off’.

visible-stats
If set to ‘on’, a character denoting a file’s type is appended to the filename when listing possible completions. The default is ‘off’.

Проверил set visible-stats on, у меня тоже ничего не меняет.

Проверил set visible-stats on, у меня тоже ничего не меняет.

Тоже сразу не понял на что оно влияет.
Наглядно видно если ввести ping<tab> с включенной опцией:


ping*  ping4@ ping6@

и с выключенной:


ping   ping4  ping6

ping4 и ping6 это симлинки, оно их помечает @
ping исполняемый, помечен *

set completion-prefix-display-length 3 — как понял, общую часть дополнения при отображении схлопывает до "___"

«Схлопывает» до многоточия.
www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html
Толковые примеры:
www.reddit.com/r/commandline/comments/kbeoe/you_can_make_readline_and_bash_much_more_user
Яркий пример архаизма в линуксе это вот такие странные комбинации. Ещё Ctrl-S и Ctrl-Q которые выполняют тот же функционал, что должна выполнять клавиша ScrollLock, но почему-то не выполняет.
Благо в современных терминалах работают более человеческие комбинации, хотя местами тоже странные: например перемещаться по словам можно по Ctrl-стрелки, но удалять по словам: Alt-Backspace
Пользователи Емакса радуются хоткеям в шелле потому что они им как родные. В прямом смысле: sh и bash используют те же хоткеи что и Емакс.

Впрочем, команда set -o vi позволит переключится в режим ввода «как в vi». Собственно, у вас как в vi будет два режима: режим команд и режим редактирования. set -o emacs переключит ввод обратно, если что.

И еще. Meta — это не Alt. Meta — это Meta. Просто Emacs разрабатывали под вот такие клавиатуры:

image

На современных клавиатурах таких кнопок конечно же нет, поэтому приходится использовать Alt вместо Meta и Win вместо Super.
Да — всё верно.

Только похоже многие(так кажется) часто сначала изучают командную строку и привыкают к этим emacs-клавишам, а потом (сильно не сразу) изучают vi — в итоге (как и я) знают vi и не пользуюсь emacs, но к этим хоткеям уже попривыкли.
НЛО прилетело и опубликовало эту надпись здесь
Именно так, а всё потому что ввод обрабатывалется с помощью библиотеки 'readline'.
Я первым делом после прочтения заголовка статьи отправился искать 'emacs'.

LinuxCertifiedInstructor
Написать целое полотно по использованию Emacs-like команд в Bash и при этом не указать откуда это пришло (а заодно не указать про существование vim-mode, и, соответственно совершенно иного поведения shell), имхо не достойно уровня сертифицированного инструктора по линуксу. Исправьте.

Edit.
Особенно в разрезе вашего предыдущего комментария про vim/emacs. Если это матерьял для новичков, то я считаю особенно важным с ходу обьяснить что к чему. И может даже посоветовать попробовать vim-mode.
Что за мания про комменты «достойно-недостойно уровня инструктора»?)…
Скажу по секрету не в одной сертификации (которые знаю и сдавал. Если знаете такую напишите название) не на уровень специалиста, ни на преподавателя не спрашивают про vim-mode в командной строке bash.

Новички обычно на этой теме не знают про vim, и до конца курса могут и не услышать совсем про emacs (извините фанаты emacs, но так часто происходит — ну есть что другое изучить на курсе вместо этого) — количество дней ограничено чтобы рассказать абсолютно всё и по каждому вопросу еще и экскурс в истории провести… тут скорее если вопрос из зала подтолкнет к этой теме.

Но соглашусь в статью стоит добавить
Что за мания про комменты «достойно-недостойно уровня инструктора»?)…

Рискну предложить что «сертификат», это лишь бумажка подтверждающая что вы умеете выучить правильные ответы на конкретные вопросы, а реально стоящий инструктор/лектор вам покажет что, зачем и почему.
Сам сдавал сертификационные экзамены, среди которых были и Juniper/RedHat/Amazon. Прекрасно знаю насколько они «ниочём» с точки зрения применения реальных знаний в реальной ситуации если не понимаешь откуда ноги растут.

Новички обычно на этой теме не знают про vim, и до конца курса могут и не услышать совсем про emacs

Это и считаю упущением. Может это просто я такой, но я предпочитаю когда мне вместе с каким-то знанием той или иной вещи обьясняют «почему так» — с историей происхождения, если таковая имеется.

Приведу пример — '\n' как обозначение конца файла.
Мало того что куча людей до конца не понимает разницу между '\n' и «новой строкой», так ещё даже ярые защитники POSIX стандарта не всегда знают откуда это взялось и не думают на тему того, нужно-ли это повсеместно применять на проекте, где нет ни одного исходника Си или Makefile, кроме как в угоду POSIX совместимости.
Сертификат ни то чтобы совсем «ни о чем», скорее как раз их цель проверить наличие реальных знаний, хотя получается скорее поверхностно оценить.

Ладно, забили — а то будем бесконечно обоюдно хвалится знаниями.
Были б курсы по месяцу, а лучше полгода… вот тогда бы… эх.
Класс, всегда полезно вспомнить. Но, set -o vi и установка FZF помогают частично упростить работу в строке.

Оформление материала офигенное, респект!


Но вот структура… Хоткеи консоли (tty) перепутаны с readline и собственными эвристиками баша… С точки зрения моторики это не важно, с точки зрения стройной картины в голове — очень важно.

Ну, смотрите, правильно было бы объяснять откуда что приходит.


Уровень первый: терминал. Нажимаете вот эти кнопки, их терминал преобразует в ioctl для лидера сесссии (или как он преобразует? Я вот не знаю).


Следующий уровень: readline. Кто использует, как обрабатывает. Кнопки.


Следующий уровень: приятности баша.


Потому что из вашего описания мне трудно понять, кто именно обрабатывает, например, ctrl-r. Это readline или баш? А ещё я могу нажать Crtl-Shift-u,3344,Enter и получить на экране вот это: "㍄". Так что X'ы тут тоже надо упомянуть. Включая keymap и compose.

Понятно, просто изначально статья была про полезные клавиши знание которых полезно при работе в командной строке — такой «Необходимый минимум по работе в командной строке», которые я далее сгруппировал по тема «Редактирование, Перемещение,...». Про readline, bash, stty было совсем не основное, оно всплыло только чтобы объяснить почему в каком-нибудь другом дистрибутиве, отличном от мною используемом, какие-нибудь клавиши заработают не так.

Про графику кстати упомянул.
Сам всегда пользовался и xmodmap и sxhkd — но это уж лишнее для этой темы
Первые две комбинации клавиш достаточно важные, и часто «недавно перешедшие с Windows на Linux» НЕправильно их используют: продолжая, как в DOS, для завершения команд использовать комбинацию «Ctrl-z», что неверно. В Linux же для того, чтобы попросить (команде посылается сигнал SIGINT) приложение прервать свою работу, используется Ctrl-c.
Вообще-то в DOS (и консоли Windows) назначение Ctrl-C ровно то же, что и в *nix. А вот Ctrl-Z — это аналог никсового Ctrl-D.
Забавно если «Ctrl-с» в Windows по разному трактуется (или трактовался в каких-то версиях) в консоли и в графике. Ну вполне вероятно могу в том что касается Windows ошибаться — всё так почти совсем её лет 15 как не использую.
А что, в линуксе не по-разному, что ли?
по разному.
Но в Линуксе мне эти отличия более понятны — всё ж разные группы людей в разное время делали разные части системы.
Как будто в винде не разные.
Да что о gui говорить — много ли приложений на ncurses, в которых Ctrl-C их завершает?

Спасибо за Alt+#! Осталось отучиться от Ctrl+a # Enter

Знает ли кто-нибудь, как бороться с проблемой, что иногда командная строка bash отображается с некоторым «смещением», так что видимые правки не совпадают с реальными?
Простое нажатие Enter исправляет проблему, но для этого надо успеть понять, что текущая строка «битая» (например, это можно проверить нажатием Home — признаком будет то, что курсор окажется на пару символов сдвинутым относительно ожидаемой позиции).

P.S. Понимаю, что это оффтоп, но это косвенно связано с темой статьи, т.к. необходимость постоянно держать в голове эту потенциальную проблему «убивает» производительность.
ctrl-L в подобной ситуации должно помочь
предположу (почти уверен), что проблема в том что в приглашении используете последовательности для, например, подкраски цветами приглашения и не «экранируете» их (обрамить в "\[" и "\]") — и в итоге bash (или терминал) эти символы цвета воспринимает как символы и считает их при переносе строк, хотя и не отображает их терминал.

То есть неправильно (будет с смещением) делать приглашение так:
PS1="\e[7;32m>>>\e[0m "

а правильнее так (будет без смещения):
PS1="\[\e[7;32m\]>>>\[\e[0m\] "

иногда терминал "ломается", помогает stty sane

при выводе некоторых непечатных управляющих символов терминал «ломается» — починить можно «stty sane» или «reset» (причем набирая не смотря на отображаемые символы-крокозябры и нажать «Enter»)

stty sane у меня всегда шёл в паре с setterm reset в 99 процентах случаев помогает.

хозяйке на заметку, ctrl-d как окончание файла, но не просто, а только на новой строке, то есть


текст
ххххх
<enter> ctrl-d

если не хочется заканчивать текст новой строкой, можно дважды нажать ctrl-d


текст
ххх ctrl-d ctrl-d
Кроме Ctrl-w/u/k есть еще Alt-d — удалить вперед до конца слова. Непонятно только почему она с Alt, когда все остальные с Ctrl.

Не читал все комменты, если не написали, то в bash есть опция," set -of vi" Если привыкли к vim, то в bash е будет очень удобно, поиск по бэк слешу, история n или N undo, redo как в vim, единственное, если переходите в визуальный режим, то открывается vim, а в нём нет автодополнений bash

одно из самых "спасающих" сочетаний это ctrl-y
все удаления текста, по сочетаниям клавиш (кроме Backspace/Del) можно восстановить взад.
то есть например:


$ echo test <alt-Backspace>

даёт


$ echo 

последущее нажатие ctrl-y восстанавливает все обратно в


echo test
Тут лучше:
Ctrl-_ (точнее, нужно нажать Ctrl Shift -) или Ctrl-x Ctrl-u – отменяет последние правки при редактировании командной строки.


а «Ctrl-y» не отмена удаления, а «вставить вырезанное» и очень удобно использовать с Alt-y (позволяет «прокручивать» варианты вставки из буфера).

ctrl-x ctrl-u это что то новое, никогда не пользовался, прикольно.


Не думаю что запомню, но сам факт, что оно там где то есть и его можно найти :)


и да, конечно ctrl-y это вставка удалённого

Если не ошибаюсь, то при "set -o vi" подобное поведение достигается нажатием клавиш dw (удалить "test") далее u (восстановит "test")

скорее тут подобно сделает — "db" (удалит от текущего положения курсора до предыдущего знака пунктуации),
а "dw" — удалит до начала следующего слова.

А «u» — верно, отменить предыдущую правку, то есть здесь воcстановит «test»
Ну или, тот же результат, «p» — вставит вырезанное при помощи db или dw
А если отключить xon/xoff (stty -ixon), то можно наряду с ctrl+r использовать ctrl+s для поиска вперед.
Удобно когда при обратном поиске случайно пролистаешь команду, то можно вернуться.
> Ctrl-z – сигнал SIGTSTP
кажется, и у меня в убунте и у вас на скрине, в выводе `stty -a`, ^S — это стоп а ^Z — саспенд:
stop = ^S; susp = ^Z;

Почему? Наверное, в терминах stty обозначение susp равняется сигналу TSTP? Тогда что делает ^S?

Фактически посылается TSTP по ^Z:

$ perl -E '$SIG{TSTP}=sub{ say "here is STOP"}; $SIG{INT}=sub{ say "here is INT"}; sleep 999'

^Chere is INT

$ perl -E '$SIG{TSTP}=sub{ say "here is STOP"}; $SIG{INT}=sub{ say "here is INT"}; sleep 999'

^Zhere is STOP
Кажется, вот и ответ из man stty:
stop CHAR
CHAR will stop the output

susp CHAR
CHAR will send a terminal stop signal


Т.е. stop прекращает вывод, как-то обрубает весь stdout. Непонятно как.
А susp действительно посылает, только не stop, а tstop?
Спасибо за выдержку из «man stty».
Да всё верно — «Ctrl-z» посылает SIGTSTP («Stop typed at terminal» согласно «man 7 signal»), и это совсем не сигнал SIGSTOP
А где Ctrl+L задан?
Не видать его что-то в stty -a
Это в readline, который использует bash — можно в «man 1 bash» или в «man 3 readline» прочитать:
clear-screen (C-l) Clear the screen, then redraw the current line, leaving the current line at the top of the screen. With an argument, refresh the current line without clearing the screen.


Комбинацию указал в разделе статьи с названием «терминал», не потому что это часть настроек stty (как остальные в этом разделе), а скорее по тому что больше относится к терминалу, чем к «редактированию-перемещению» и потому что в других разделах ей места не было, а показать её надо было.

^^^ В правом терминале отображаю историю команд.

А чем Вы её там отображаете, если не секрет? Просто интересно: знаю несколько способов, но это не они.

tail -f ...| grep…
tail -n0 -f $HISTFILE | egrep --color -n "(|Нужные|слова|например|sudo)" 


Только у меня еще включена в ~/.bashrc:
shopt -s histappend
export PROMPT_COMMAND="history -a; history -c"


А какие способы знаете вы?

Только попсу: tail -f, less -F
Меня номера строк насторожили. А они, оказывается, извне, от грепа. За egrep спасибо, я до сих пор про него как-то не слышал, а зря.

Подскажите как вы сделали чтобы история автоматически выдавала вновь вводимые команды. Разве эти два терминала не в отдельных сессиях?
Ответ на этот вопрос в сообщении выше:
у меня еще включена в ~/.bashrc:
shopt -s histappend
export PROMPT_COMMAND="history -a; history -c"


Да в отдельных, но две указанные строки включают синхронизацию между сессиями — буквально каждая новая команда пишется в ~/.bash_history сразу же как появилось следующее приглашение командной строки. То есть «по каждому чищу» пишет на диск и считывает с диска в память текущей сессии.

Упс, поправка (опция не "-c", а "-n"):

shopt -s histappend
export PROMPT_COMMAND="history -a; history -n"
Часто, когда дописываются аргументы команд по Tab, дописываются имена файлов. Но стоит также отметить, что, в зависимости от контекста, по Tab дописываются и имена переменных (аргументы, начинающиеся с символа «$»), имена пользователей (аргументы, начинающиеся с символа «~»)


Маленькое уточнение — не только файлов, а путей в принципе (файлы, директории, пайпы, ссылки — все что может быть в пути)

Кроме того, не только переменных, но еще и алиасов и имен функций.

Кроме того многие команды могут добавлять в bash-completion свои собственные правила для автокомплита опций, что многие и сделали (в убунту можно глянуть список тут /usr/share/bash-completion/completions), например:
chmod --h
Маленькое уточнение — не только файлов, а путей в принципе (файлы, директории, пайпы, ссылки — все что может быть в пути)
Имеется в виду «файлов» в общем смысле, а не только регулярных, то есть как раз все 7типов какие в Линуксе используются (socket, named pipe, directory, symlink, block special file, character special file, ну и regular file).

Кроме того, не только переменных, но еще и алиасов и имен функций.
Согласен. (и встроенные команды в bash тоже).

bash-completion
Просто тут была скорее про клавиши чем про работу автодополнения — в курсе в этой теме и про команду complete пример показываю — как свои автодополнения к чему-нибудь прикрутить.
Например (к команде rpm, автодополнение списка установленных пакетов):
complete -W "-qi -qa -ql $(rpm -qa)" rpm
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.