20081107

Приёмы работы в коммандной строке *NIX

По мотивам дискуссии на слэшдоте. Всякие полезные, занятные и совсем бесполезные мелочи, позволяющие сделать работу в коммандной строке удобнее и приятнее. Кое-что добавил уже от себя. Многим это, конечно, и так известно, но коллективный опыт всегда больше. Я для себя кое-что почерпнул.

  1. Началось с упоминания о write, которая позволяет слать сообщения другим пользователям системы.
    $ w

    sergey pts/1 :0.0 11:34 3.00s 0.18s 0.18s bash
    $ write sergey pts/1
    hi there!
    ^D
    Хотя, если права позволяют, можно просто писать
    $ echo '^LAll files deleted.' > /dev/pts/1
  2. TAB-TAB-TAB :-)

  3. Не обошлось без шуток. Мне понравился «коан»:
    $ grep '' /dev/null
    И «про уток»:
    $ du -cks
  4. А screen позволяет подключаться и отключаться к виртуальному терминалу, который работает даже если выйти из системы, имеет кучу применений, от запуска «долгоиграющих» процессов на удалённых машинах до экстремального программирования; также очень полезен для создания «общего» терминала (screen -x), можно видеть, что делает другой человек, или показывать ему то, что делаешь. На удалённой машине обычно запускаю так:
    $ screen -RD
    Список виртуальных терминалов: ^Aw. Выбор терминала: ^Aцифра. Отсоединися от screen-а (не закрывая его терминалы): ^Ad

  5. cd -, чтобы вернуться в предыдущий каталог (до cd) и cd `pwd -P`, чтобы перейти по настоящему пути (если пришёл по символической ссылке). Ещё полезны pushd и popd (запомнить текущий каталог и потом в него вернуться).

  6. history | grep шаблон, чтобы вспомнить, что уже делал. ^Rфрагмент-команды^R^R^R…, чтобы найти и повторить ранее выполненную команду. ^N и ^P чтобы прокручивать историю bash вперёд и назад.

  7. Чтобы повторить последнюю команду:
    $ !!
    И при редактировании команды — ESC., чтобы подставить последний аргумент последней команды. В эту же категорию попадает ещё целая пачка трюков (man bash, /^HISTORY EXPANSION).

  8. Если в режиме поиска команды нажать ^O, то будет исполнена текущая команда из истории и после этого будет набрана следующая команда из истории. Можно автоматизировать весь цикл редактирование-компиляция-исполнение. Проще объяснить на примере:
    $ vi foo.c
    $ gcc -o foo{,.c}
    $ ./foo
    $ ^Rvi^O^O^O^O^O…
  9. Для любителей vi можно переключить сочетания клавиш
    $ set -o vi
    после этого ESC чтобы перейти в коммандный режим и режима вставки, k/j, чтобы прокручивать историю команд, /шаблонENTER, и n/N, чтобы искать по истории. Если честно, хотя и и пользуюсь постоянно vim, в bash по-умолчанию всё равно Emacs-овские сочетания…

  10. META-t в bash, чтобы поменять местами аргументы.

  11. ^S и ^Q, чтобы приостановить и продолжить вывод в терминал («пауза»).

  12. reset обычно приходится набирать вслепую (после неудачного вывода бинарного файла в stdout). Чаще достаточно ^L.

  13. ssh и много-много-много его применений. -XC для запуска иксовых приложений на удалённой машине с локальным X-сервером. -D, -L и -R для создания защищённых тунелей. Требует отдельного обсуждения.

  14. sftp, имитация FTP-клиента поверх SSH, и sshfs для подключения удалённой файловой системы поверх SSH (я бы добавил сюда scp и rsync).

  15. wc -l, чтобы подсчитать количество строк. nl, чтобы добавить номера строк.

  16. sort для сортировки строк. sort -n — числовая сортировка.

  17. … | rev | sort | rev, чтобы сгруппировать строки по окончаниям.

  18. du -sh * | sort -n неплохая замена графическому baobab (точнее наоборот).

  19. head -количествострок и tail -количествострок для печати начала и конца файла, tail -f, чтобы следить за файлом, который ещё пишется (например, лог). Полезный вариант: tail -F возможно-несуществующий-файл.

  20. strings, чтобы увидеть человеко-читаемые строки, встречающиеся в файле. См. пример в предыдущем посте.

  21. grep, чтобы отобрать только нужные строчки, | grep шаблон. Мне часто полезны опции -r (рекурсивно во вложенных подкаталогах) и -i (без учёта регистра). Да, grep поддерживает также опцию --color (нагляднее).

  22. awk для того, чтобы разбить строчку на поля и вытащить только нужные. | awk -F'разделитель' '{print $номер-поля;}'
    $ echo "a,b,c" | awk -F',' '{print $2;}'
    В простых случая можно использовать cut -d 'разделитель' -f список-полей:
    $ echo 'a,b,c' | cut -d ',' -f 2
  23. Обратные апострофы (`команда` или $(команда)) подставляют результат выполнения команды.
    $ NOW=$(date -u)

    $ echo $NOW
    Птн Ноя 7 12:17:07 UTC 2008
  24. Выполение задания в назначенное время (один раз):
    $ echo 'команда' | at время
    Говорящий будильник:
    $ echo 'for i in `seq 1 10`; do echo wake up, internet was updated | festival --tts ; done;' | at 08:00
    Такой вот одноразовый cron.
  25. find очень стоит того, чтобы научиться ей пользоваться. Особенно полезна опция -exec команда, в которой {} заменяет имя найденного файла \;. Для меня стало открытием, что -exec можно использовать также в качестве условия для выбора файлов:
    $ find . -exec grep -q 'шаблон' {} \; -print
  26. echo * вместо ls. ls -v для «правильной» сортировки пронумерованных файлов (12.txt после 2.txt). ls -tgo покажет недавно изменённые файлы первыми.

  27. Мне очень нравятся фигурные скобки в bash. Так можно писать:
    $ gcc -o foo{,.c}
    $ convert /длинный/путь/к/image.{eps,jpg}
    вместо
    $ gcc -o foo foo.c
    $ convert /длинный/путь/к/image.eps /длинный/путь/к/image.jpg
  28. Управление процессами: ^Z, bg, fg, jobs, kill %номерзадачи. И тогда ps нужен гораздо реже. А htop, кстати, удобнее, чем просто top.

  29. Раскрытие переменных в bash: ${var%ending-to-remove}newending, ${var/find/replace}, ${var//find/replace-all}, ${var#prefix-to-remove}.

  30. Циклы в bash: for f in * ; do команды ; done чтобы обработать все файлы (*), for i in `seq 1 10` ; do команды ; done чтобы перебрать все i от 1 до 10. В скриптах удобно использовать неявные циклы вида while [ $# -gt 0 ] ; do arg=$1; shift; … ; done.

  31. Широко известно про dd для создания образов дисков, их бэкапа и восстановления.
    # dd if=/dev/раздел of=/media/backup/образ-раздела bs=1k conv=noerror,sync
    Менее известный приём: killall -USR1 dd, чтобы увидеть, сколько уже сделано.

  32. lsof /media/том, чтобы узнать, какой процесс использует файлы на нежелающем отсоединяться диске. Может пригодится и для решения проблем с файлами устройств (/dev/что-нибудь).

    Другой вариант — fuser -v /media/том. Тоже очень удобно.

  33. eject, чтобы выдвинуть подставку для кофе.

  34. cal 11 2008 и мы вспоминаем, что сегодня пятница. date и узнаём, который час.

  35. Из всевозможных «калькуляторов» под рукой почти всегда будет вот этот:
    $ awk 'BEGIN{ print exp(1)+2^(1.0/3); }'
    Ещё традиционный вариант для интерактивного использования — bc -l. В нём, правда, нестандартные названия функций: s(x) — синус, c(x) — косинус, a(x) — арктангенс, l(x) — натуральный логарифм, e(x) — экспонента, x^n — целая степень. Предыдущее выражение можно посчитать так:
    $ bc -l
    ...
    e(1)+e((1/3)*l(2))
    3.97820287835391840011
    А целые числа умеет складывать и bash: echo $((2+2)).

  36. time команда чтобы засечь время выполнения задачи.

  37. ulimit -m размер-памяти-в-килобайтах ограничить максимальный размер памяти процессов, вызываемых из текущей оболочки. Вариант: -v размер-памяти-в-килобайтах для ограничения размера виртуальной памяти. Полезно, если есть опасения, что процесс слишком жадный.

  38. nice -n +10 команда выполнить команду с пониженным на 10 приоритетом. Полезно, если команда работает долго, требует много процессорного времени, а оно нужно и для другого.

  39. Доб. 2008-11-26: чтобы после поиска по истории вернуться к последним коммандам, ESC >.



Дополнения можно писать в комментариях. Доб. 2009-09-29: cut, bc -l и fuser.