Классика командной строки


Это перевод с английского на русский язык руководства «Искусство командной строки» Джошуа Леви (Joshua Levy) об основах работы в командной строке GNU/Linux. Хотя во многом это совместная работа с остальными пользователями GitHub. Лицензия: CC-BY-SA 4.0. Страница на GitHub: https://github.com/jlevy/the-art-of-command-line


От переводчика

Особенность руководства «Искусство командной строки» Джошуа Леви состоит в том, что с одной стороны это всеобъемлющий набор советов для командной строки в GNU/Linux. С другой стороны это руководство достаточно компактное и одностраничное — команды с программами командной строки описаны очень кратко и сжато. Описывается или общий смысл команды или приводится практический пример, позволяющий уяснить эту суть. После чего можно воспользоваться внешними источниками, чтобы глубже разобраться с нужной программой, например, в документации или на других сайтах, посвящённых GNU/Linux.

В некотором роде «Искусство командной строки» Джошуа Леви — это такая панорама, которая изображает целостную картину приёмов и возможностей оболочки командной строки BASH. Именно поэтому свой перевод я назвал «Классика командной строки», а не перевёл название дословно.

Это не дословный перевод руководства «Искусство командной строки» Джошуа Леви. Некоторые места я переводил исходя из общего смысла того или иного предложения. Дословный перевод на русский язык уже имеется на странице руководства на GitHub наравне с переводами на другие языки. К тому же само руководство будет ещё совершенствоваться и дополняться. Я же оставлю вариант перевода на июль 2015 года, потому что он вполне самодостаточный.

Астапчик Михаил, 2015

Содержание и введение

Рис. curl -s ’https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md’ | egrep -o ’<code>\w+</code>’ | tr -d ’`’ | cowsay -W50
Рис. curl -s ’https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md’ | egrep -o ’\w+’ | tr -d ’`’ | cowsay -W50

К умению свободно владеть командной строкой часто относятся пренебрежительно или считают это чем-то вроде магии. Но это умение явно и неявно увеличивает возможности и производительность работы любого инженера. Перед вами подборка примечаний и подсказок для командной строки, которую я считаю полезной, работая в GNU/Linux. Некоторые подсказки элементарны, некоторые довольно специфичны, есть среди них изящные и даже замысловатые. Эта небольшая по объёму подборка советов, но если Вы умеете использовать и помните все пункты этого руководства, значит Вы знаете много.

Многое из написанного ниже первоначально появились на сервисе Quora, но, учитывая тамошний интерес, думаю, что правильно будет использовать сервис Github, где люди более талантливы, чем я, и могут с готовностью предложить лучшие варианты. Если вы увидели ошибку или что-то, что может быть улучшено, то, пожалуйста, отправьте запрос. (Конечно, пожалуйста, сначала ознакомьтесь с уже существующими вопросами.)

Join the chat at https://gitter.im/jlevy/the-art-of-command-line

Описание

Область применения:

Примечания:

Основы

Изучите командную оболочку Bash. По крайней мере, просто наберите в терминале команду man bash и просмотрите вывод; это довольно легко и не займёт много времени. Альтернативные оболочки командной строки могут быть более заманчивы для изучения, но Bash является мощным инструментом, который всегда доступен (изучение только zsh, fish и т.д. может быть заманчивым, например, для работы на ноутбуке, но ограничит вас во многих других ситуациях — например, при работе с сервером).

Для русскоязычных небольшое примечание. В зависимости от дистрибутива страницы man могут быть на английском языке. Можно в таком случае попробовать стандартную опцию --help для встроенной справки о программе. Стандартная справка команды может оказаться на русском языке.

Изучите, по крайней мере, также один текстовый редактор для редактирования текстовых файлов в терминале. В идеале это Vim (vi), даже если вы предпочитаете Emacs, мощный IDE или современный хипстерский редактор кода.

Научитесь читать документацию с использованием команды справочных страниц man. Для любознательных, команда man man перечисляет номера разделов справки. Например, раздел 1 — это справка по исполняемым программам или командам оболочки (shell); раздел 5 — это форматы файлов и соглашения, например о /etc/passwd; раздел 8 — это справка о командах для администрирования системы). Находите в справке нужные команды по ключевым словам с помощью apropos. Узнайте, какие команды включены в состав оболочки — напишите help или help -d чтобы увидеть этот список.

Узнайте о перенаправлении вывода и ввода процессов с помощью > и < и о канале взаимодействия между процессами pipe (конвейере) с использованием символа |. Помните, что > — переписывает файл, а >> добавляет к файлу. Узнайте о стандартном выводе и стандартном потоке ошибок (stderr).

Выучите подстановочные символы, позволяющие задавать несколько имен команд или файлов в одном выражении: *, ? и { … }. Уясните использование в командной строке кавычек и разницу между двойными и одинарными кавычками.

Ознакомитесь с управлением процессами в Bash с помощью: &, Ctrl-Z, Ctrl-C, jobs, fg, bg, kill и т.д.

Изучите ssh, изучите основы беспарольной аутентификации через ssh-agent, ssh-add и т.д.

Изучите основы управления файлами: ls и ls -l (в частности, узнайте, что означает каждый столбец в ls -l), less, head, tail и tail -f (или даже лучше, less +F), ln и ln -s (узнать различия и преимущества жестких и мягких ссылок), chown, chmod, du (для быстрого просмотра использования диска: du -hk *). Для управления файловой системой: df, mount, fdisk, mkfs, lsblk.

Не забудьте про основы управления сетью: ip или ifconfig, dig.

Разберитесь хорошо с регулярными выражениями, а также с различными флагами grep / egrep. Опции -i , -o , -A , и -B стоит хорошо изучить.

Выучите использование менеджеров пакетов apt-get, yum, dnf или pacman (в зависимости от дистрибутива), чтобы найти и установить программы. И убедитесь, что у вас есть pip, чтобы установить утилиты и программные пакеты, написанные на Python.

Повседневное использование

В Bash, используйте Tab, чтобы завершить команды и аргументы и Ctrl-R для поиска по истории команд.

При наборе в командной строке Bash используйте Ctrl-W, чтобы удалить последнее слово, и Ctrl-U, чтобы удалить всю набранную до самого начала строку. Используйте Alt-B и Alt-F, чтобы перейти от слова к слову, Ctrl-K, чтобы удалить слова в конце строки, Ctrl-L, чтобы очистить экран. Смотри man readline для комбинаций всех клавиш по умолчанию в Bash.

Кроме того, если вы любите работу в vi-подобном режиме, то команды редактирования в командной строке могут быть установлены в этот режим с помощью set -o vi.

Чтобы увидеть последние команды, используйте history. Есть также много сокращений, как, например, !$ (последний аргумент) и !! (последняя команда), хотя их часто легко заменить на Ctrl-R и Alt-..

Чтобы вернуться к предыдущему рабочему каталогу: cd -

Если вы во время набора команды вы передумали её вводить, нажмите Alt-# — в начале команды будет добавлено # и введите команду в качестве комментария (или используйте сочетание клавиш: Ctrl-а, #, Ввод). Вы можете вернуться к ней позже с помощью истории команд.

Используйте мощную утилиту xargs (или parallel). Запомните, в xargsвы можете установить число непустых строк аргументов, прочитанных со стандартного ввода (-L), а также распараллелить процессы (-P). Если вы не уверены в том, что команда будет делать то, что нужно, используйте сначала xargs echo. Кроме того удобна опция -I{}. Примеры:

find . -name ’*.py’ | xargs grep some_function
cat hosts | xargs -I{} ssh root@{} hostname

Команда pstree -p полезна для просмотра дерева процессов.

Используйте pgrep и pkill, чтобы найти процесс или послать сигнал процессу по имени и другим атрибутам (опцию -f полезно использовать).

Узнайте, какие различные сигналы можно передавать процессам. Например, чтобы приостановить процесс, используйте kill -STOP [pid]. Полный список сигналов смотри командой man 7 signal.

Используйте nohup или disown, которые запускают указанную команду как невосприимчивую к сигналам завершения, и чей вывод будет не направлен на терминал. Таким образом, команда будет продолжать выполняться в фоновом режиме и после того, как пользователь выйдет из системы.

Проверьте, какие процессы прослушивают сеть, с помощью netstat -lntp или ss -plat (для TCP, опция -u для UDP).

Смотрите также lsof для вывода информации о том, какие файлы и сокеты используются теми или иными процессами.

В сценариях Bash используйте set -x для установки режима отладки вывода. По возможности используйте строгие режимы отладки. Используйте set -e для остановки скрипта на ошибках. Используйте set -o pipefail также, чтобы увидеть ошибки в коде, переменных и «пайпах» (хотя эта тема более тонкая). Для более сложных сценариев используйте trap.

В сценариях Bash используйте подоболочки (Subshells), которые записываются в скобках, для группы команд. Типичным примером является временный переход в другую рабочую директорию, например:

# Сделать что-то в текущей директории
(cd /some/other/dir && другие команды)
# Продолжать в оригинальном режиме

Обратите внимание, в Bash есть много видов определения переменных. Проверка существования переменной: ${name:?error message}. Например, если сценарий Bash требует один аргумент, просто напишите input_file=${1:?usage: $0 input_file}. Арифметическое определение: i=$(( (i + 1) % 5 )). Последовательности: {1..10}. Обрезка строк: ${var%suffix} и echo ${var%.pdf}.txt. Например, если var=foo.pdf, то echo echo ${var%.pdf}.txt печатает foo.txt.

Если использовать <(команда), то вывод из команды может рассматриваться как файл. Сравним, например, локальный файл /etc/hosts с файлом на внешнем компьютере:

diff /etc/hosts <(ssh somehost cat /etc/hosts)

Разберитесь с синтаксисом встроенных документов Heredoc (дословно с английского «здесь документ») в командной строке Bash, как, например, cat <<EOF …. Встроенные документы полезны для внедрения больших блоков текстовых данных в скрипт. Когда интерпретатор встречает подобную конструкцию, он направляет строки вплоть до указанного маркера (в данном случае — EOF) на входной поток команды.

В Bash соединение стандартного вывода и вывода сообщений об ошибках может быть таким образом: some-command >logfile 2>&1. Чтобы команда не оставила открытым файл, привязав его к открытому терминалу, считается хорошей практикой добавлять </dev/null.

Используйте man ascii с замечательными таблицами ASCII, где указаны шестнадцатеричные и десятичные значения символов. Для получения общей информации о кодировках: man unicode, man utf—8, и man latin1.

Используйте screen или tmux для мультиплексирования терминала, что особенно полезно для удаленных сессий SSH, потому что даёт возможность отключать виртуальные сеансы от управляющего терминала, а потом подключить снова. Более простая альтернатива для удаленных сессий, которые возможно прервать и подключиться вновь, это только dtach.

Узнайте, как в SSH пробросить порты в туннель с помощью опций -L или -D (а иногда и -R ), например, для доступа к веб-сайту с удаленного сервера.

Могут быть полезными несколько оптимизаций в конфигурации SSH; например, ~/.ssh/config содержит настройки, позволяющие избежать разрыва подключений в некоторых сетевых средах, использовать сжатие (что полезно при копировании scp на соединениях с низкой пропускной способностью), создать мультиплексирование каналов на один сервер:

TCPKeepAlive=yes
ServerAliveInterval=15
ServerAliveCountMax=6
Compression=yes
ControlMaster auto
ControlPath /tmp/%r@%h:%p
ControlPersist yes

Другие варианты настроек SSH чувствительны безопасности, и должны включаться с осторожностью, например: StrictHostKeyChecking=no, ForwardAgent=yes.

Чтобы получить разрешения на доступ к файлу в восьмеричной форме, что не доступно в ls, и что бывает нужно для настройки системы, нужно использовать что-то вроде

stat -c ’%A %a %n’ /etc/timezone

Для интерактивного выбора значений из вывода другой команды, используйте percol или fzf.

Для взаимодействия с файлами на основании выходного списка другой команды (например, git ), используйте fpp (PathPicker).

Для простого веб-сервера для всех файлов в текущем каталоге (и подкаталогах), доступных для всех, кто в сети, используйте: python -m SimpleHTTPServer 7777 (для порта 7777 и Python 2) и python -m http.server 7777 (для порта 7777 и Python 3).

Чтобы выполнить определенную команду с привилегиями суперпользователя, используйте sudo и sudo -u для выполнения команды с привилегиями другого пользователя.

Обработка файлов и данных

Чтобы найти файл по имени в текущем каталоге используйте подобное find . -iname ’*something*’. Чтобы найти файл в любом месте системы, используйте locate что-нибудь (но имейте в виду, updatedb, возможно, ещё не проиндексировал недавно созданные файлы).

Для общего поиска в исходниках или файлах данных (более продвинутого, чем grep -r), используйте ag.

Для преобразования HTML в текст: lynx -dump -stdin.

Для Markdown, HTML и всех видов преобразования документов, попробуйте pandoc.

Если необходимо обработать XML, используйте старый добрый xmlstarlet.

Для JSON используйте jq.

Для Excel или CSV файлов, csvkit предоставляет набор инструментов: in2csv, csvcut, csvjoin, csvgrep и т.д.

Для Amazon S3 s3cmd удобнее, а s4cmd быстрее. Для остальных сервисов Амазона используйте стандартный aws.

Нужно иметь представление об утилитах сортировки sort и uniq. Для Uniq — опции -u и -d. Рассмотрите также утилиту сравнения строк в файле comm.

Требуется знать о cut , paste и join для манипулирования текстовыми файлами. Многие люди используют cut, но забывают о join.

Нужно знать об утилите статистики текстового файла wc, и уметь выводить количество строк (-l), символов (-m), слов (-w) и байтов (-c).

Нужно знать о tee для копирования из стандартного ввода в файл или на стандартный вывод, как, например, ls -al | tee file.txt.

Знайте, что языковая «локаль» (locale) влияет на множество инструментов командной строки неочевидным образом, в том числе — и на порядок сортировки и производительность. В большинстве инсталляций Linux будут установлены языковые параметры LANG автоматически. Но имейте в виду, параметры сортировки изменятся, если вы измените локаль. Учитывайте, что функции интернационализации i18n могут сделать выполнение сортировки или каких-либо других команд значительно медленнее. В некоторых ситуациях вы можете спокойно игнорировать медленные процедуры i18n и использовать традиционный байт-ориентированный порядок сортировки, используя export LC_ALL=C.

Знайте основы awk и sed. Например, суммирование все чисел в третьей колонке текстового файла: awk ’{ x += $3 } END { print x }’. Это, вероятно, в три раза быстрее и в три раза короче эквивалентной программы на Python.

Заменить все вхождения строки, в одном или нескольких файлах:

perl -pi.bak -e ’s/old-string/new-string/g’ my-files-*.txt

Чтобы переименовать много файлов за один раз в соответствии с паттерном, используйте rename. Для сложных переименований может помочь repren.

# Восстановление файлов резервной копии foo.bak -> foo:
rename ’s/\.bak$//’ *.bak

# Полное переименование имен файлов, каталогов и содержимого foo -> bar:
repren --full --preserve-case --from foo --to bar .

Используйте shuf, чтобы перетасовать или выбрать случайные строки из файла.

Хорошо разберитесь с опциями замечательной утилиты sort для сортировки в алфавитном или нумерологическом порядке строк текста, разделённых на поля, колонки и т.д. Для нумерологической сортировки используйте опции -n . Узнайте, как работают ключи (-t и -k). В частности, обратите внимание, в каких случаях нужно ставить точку в числовых параметрах опции -k, а в каких — запятую. Опция пересортировки -s может быть полезной. Например, для сортировки сначала по полю 2, а потом уже по полю 1 можно использовать sort -k1,1 | sort -s -k2,2. Используйте опцию -h для представления вывода чисел команды sort в удобочитаемом виде (наподобие du -h)

Если вы когда-нибудь понадобится написать знак табуляции в командной строке (например, как аргумент опции -t для сортировки), нажмите ctrl-v [Tab] или наберите $’\t’ (последнее лучше, так как вы можете скопировать/вставьте это).

Стандартные инструменты для патча исходного кода diff и patch. Посмотрите также diffstat для краткой статистики diff. Примечание: diff -r работает для целых каталогов. Используйте diff -r tree1 tree2 | diffstat для описания изменений.

Для бинарных файлов, используйте hd для просмотра шестнадцатеричных дампов и bvi для бинарного редактирования.

Кроме того в бинарных файлах strings (плюс grep и т.д.) позволяет найти кусочки текста.

Построить разницу между двумя бинарными файлами (дельта-разница) позволяет xdelta3.

Для преобразования текстовых кодировок попробуйте iconv. Или uconv для более сложных случаев; он поддерживает некоторые дополнительные вещи Unicode. Например, команда ниже переводит строки в нижний регистр и удаляет все акценты:

uconv -f utf—8 -t utf—8 -x ’::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ’ < input.txt > output.txt

Чтобы разделить файлы на куски, смотрите split (разделить по размеру) и csplit (разделить шаблоном).

Используйте zless, zmore, zcat и zgrep для работы с сжатыми файлами.

Отладка системы

Для веб-отладки curl и curl -I, или wget как эквивалент, или более современной httpie.

Чтобы узнать статус диска, CPU, состояния сети, используйте iostat, netstat, top (или лучше htop), и (особенно) dstat. Хорошо для быстрого получения информации о том, что происходит в системе.

Для более детального обзора системы используйте glances. Программа представит вам несколько уровней статистики системы в одном окне терминала. Очень полезно для быстрой проверки нескольких систем.

Чтобы узнать состояние памяти, нужно запускать и понять вывод free и vmstat. В частности, будьте в курсе "cached" — это данные в памяти, которые загружены с жесткого диска и используется для супер-быстрого к ним доступа, а по сути, эта кэшированная память свободна.

Отладка системы Java — это отдельный вопрос. Но есть простой трюк для JVM Oracle и некоторых других виртуальных машин Java: вы можете запустить kill —3 <pid> и получить трассировку стека и данные heap-памяти (в том числе детализацию сборщика мусора, которая может быть весьма информативна) в стандартный поток ошибок или логи.

Используйте mtr как лучший трассировщик, чтобы определить проблемы с сетью.

Для просмотра того, чем заполнен диск, используйте ncdu, который экономит время на обычных командах, таких как du -sh *.

Чтобы обнаружить, какой разъем или процесс использует полосу пропускания, попробуйте iftop или nethogs.

Инструмент ab (поставляется с Apache) является полезным для быстрой и черновой проверки производительности веб-сервера. Для более сложных испытаний под нагрузкой, попробуйте siege.

Для более серьезной отладки сети: wireshark, tshark или ngrep.

Необходимо знать о strace и ltrace. Это может быть полезно, если программа не запускается, или произошло зависание или сбой, и вы не знаете почему. Или вы хотите получить общее представление о производительности программы. Обратите внимание на опцию профилирования ( -c ) и возможность подключаться к работающему процессу ( -p ).

Помните о ldd, чтобы проверять разделяемые библиотеки и т.д.

Умейте подключаться к запущенному процессу с помощью gdb и получить отладочную информацию.

Используйте /proc. Это удивительно полезно иногда при отладке живых проблемы. Примеры: /proc/cpuinfo, /proc/xxx/cwd, /proc/xxx/exe, /proc/xxx/fd/, /proc/xxx/smaps.

При отладке, если что-то пошло не так, sar может быть полезной. Она показывает историю статистических данных о CPU, памяти, сети, и т.д.

Для более глубокого анализа систем и производительности анализирует посмотрите в сторону stap (SystemTap), perf и sysdig.

Удостоверьтесь, с каким дистрибутивом вы работаете: lsb_release -a

Используйте dmesg для просмотра вывода буфера сообщений ядра. Это может помочь при проблемах аппаратного обеспечения или драйвера.

Однострочники

Объединим всё в одно.

Полезно иногда сделать пересечение, объединение или разность текстовых файлов с помощью sort / uniq. Предположим, a и b — текстовые файлы, которые различны. Этот однострочник быстр, и работает с файлами произвольного размера, вплоть до многих гигабайт. (Сортировка не ограничивается размером памяти, хотя, возможно, потребуется использовать опцию -T , если /tmp находится на маленьком корневом разделе.) Смотри также выше примечание о LC_ALL и sort с опцией -u.

cat a b | sort | uniq > c # c — это объединение a и b
cat a b | sort | uniq -d > c # c — это пересечение a и b
cat a b b | sort | uniq -u > c # c — это разница a и b

Используйте grep . *, чтобы визуально изучить все содержимое всех файлов в каталоге — например, каталоги, заполненных файлами конфигурации /sys, /proc, /etc.

Суммирование всех чисел в третьей колонке текстового файла. Это, вероятно, в три раза быстрее и в три раза короче эквивалентной программы на Python.

awk ’{ x += $3 } END { print x }’ myfile

Однострочник, если нужно увидеть размер и даты на дереве файлов. Это как рекурсивный ls -l , но более читабельный, чем ls -lR:

find . -type f -ls

Используйте мощную утилиту xargs (или parallel). Примечание, в xargsвы можете установить число непустых строк аргументов, прочитанных со стандартного ввода (-L), а также распараллелить процессы (-P). Если вы не уверены, что команда будет делать то, что нужно, используйте сначала xargs echo. Кроме того удобна опция -I{}. Примеры:

find . -name ’*.py’ | xargs grep some_function
cat hosts | xargs -I{} ssh root@{} hostname

Скажем, у вас есть текстовый файл, как, например, журнал веб-сервера, и нужны строки со значением, например, acct_id. Если вы хотите подсчитать, сколько запросов для каждого acct_id:

cat access.log | egrep -o ’acct_id=[0—9]+’ | cut -d= -f2 | sort | uniq -c | sort -rn

Запустите эту функцию, чтобы получить случайный совет из этого документа (разбирает Markdown и извлекает элемент):

function taocl() {
curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md |
pandoc -f markdown -t html |
xmlstarlet fo --html --dropdtd |
xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" |
xmlstarlet unesc | fmt —80
}

Неприметные, но полезные

Другие источники

Удивительные оболочки: Дополняемый список инструментов и ресурсов для командной строки.

Strict mode: Для перфекционистов.

[Отказ от ответственности

За исключением некоторого, код написан так, что другие могут прочитать его. С силой приходит ответственность. То, что вы можете сделать что-то в Bash, не обязательно означает, что вы это должны делать! ;)

Лицензия

Рис. Creative Commons License
Рис. Creative Commons License

Эта работа распространяется по лицензии Creative Commons Attribution-ShareAlike 4.0 International License.

Ⓜ ⬇ 2015-07-09