Вот уже как неделю английская версия the art of command line висит в секции trending на Github. Для себя я нашел этот материал невероятно полезным и решил помочь сообществу его переводом на русский язык. В переводе наверняка есть несколько недоработок, поэтому милости прошу слать пулл-реквесты мне сюда или автору оригинальной работы Joshua Levy вот сюда. (Если PR отправите мне, то я после того, как пересмотрю изменения отправлю их в мастер-бранч Джоша). Отдельное спасибо jtraub за помощь и исправление опечаток.




(тсс, в маркдауне читабельнее)

Описание


Основное:
  • Данная публикация предназначена как для новичков, так и для опытных людей. Цели: объемность (собрать все важные аспекты использования командной строки), практичность (давать конкретные примеры для самых частых юзкейсов) и краткость (не стоит углубляться в неочевидные вещи, о которых можно почитать в другом месте).
  • Этот документ написан для пользователей Linux, с единственным исключеним – секцией “MacOS only“. Все остальное подходит и может быть установлено под все UNIX/MacOS системы (и даже Cygwin).
  • Фокусируемся на интерактивном Баше, но многие вещи так же могут быть использованы с другими шеллами; и в общем применимы к Баш-скриптингу
  • Эта инструкция включает в себя стандартные Unix команды и те, для которых нужно устанавливать сторонние пакеты – они настолько полезны, что стоят того, чтобы их установили

Заметки:
  • Для того, чтобы руководство оставалось одностраничным, вся информация вставлена прямо сюда. Вы достаточно умные для того, чтобы самостоятельно изучить вопрос более детально в другом месте. Используйте apt-get/yum/dnf/pacman/pip/brew (в зависимости от вашей системы управления пакетами) для установки новых программ.
  • На Explainshell можно найти простое и детальное объясение того, что такое команды, флаги, пайпы и т.д.

Основы


  • Выучите основы Баша. Просто возьмите и напечатайте man bash в терминале и хотя бы просмотрите его; он довольно просто читается и он не очень большой. Другие шеллы тоже могут быть хороши, но Баш – мощная программа и Баш всегда под рукой (использование исключительно zsh, fish и т.д., которые наверняка круто выглядят на Вашем ноуте во многом Вас ограничивает, например Вы не сможете использовать возможности этих шеллов на уже существующем сервере).
  • Выучите хотя бы один консольный редактор текста. Идеально Vim (vi), ведь у него нет конкурентов, когда вам нужно быстренько что-то подправить (даже если Вы постоянно сидите на Emacs/какой-нибудь тяжелой IDE или на каком-нибудь модном хипстерском редакторе)
  • Знайте как читать документацию через man (для любознательных – man man; man по углам документа в скобках добавляет номер, например 1 – для обычных команд, 5 – для файлов, конвенций, 8 – для административных команд). Ищите мануалы через apropos, и помните, что некоторые команды – не бинарники, а встроенные команды Баша, и помощь по ним можно получить через help и help -d.
  • Узнайте о том, как перенаправлять ввод и вывод через > и < и пайпы |. Помните, что > – переписывает выходной файл, а >> добавляет к нему. Узнайте побольше про stdout and stderr.
  • Узнайте побольше про file glob expansion with * (and perhaps ? and {}), кавычки а так же разницу между двойными " и одинарными ' кавычками. (Больше о расширении переменных читайте ниже)
  • Будьте знакомы с работой с процессами в 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 (некоторые из тех, что вы найдете ниже легче всего установить через pip)

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


  • Используйте таб в Баше для автокомплита аргументов к командам и ctrl-r для поиска по истории командной строки
  • Используйте ctrl-w в Баше для того, чтобы удалить последнее слово в команде; ctrl-u для того, что бы удалить команду полностью. Используйте alt-b и alt-f для того, чтобы бегать между словами команды, ctrl-k для того, чтобы прыгнуть к концу строки, ctrl-l для того, чтобы очистить экран. Гляньте на man readline чтобы узнать о всех шорткатах Баша. Их много! Например, alt-. бежит по предыдущим аргументам команды, а alt-* расширяет глоб.??
  • Если Вам нравятся шорткаты Вима сделайте set -o vi.
  • Для того, чтобы посмотреть историю введите history. Так же существует множество аббривиатур, например !$ – последний аргумент, !! – последняя команда, хотя эти аббревиатуры часто заменяются шорткатами ctrl-r и alt-..
  • Для того, чтобы прыгнуть к последней рабочей директории – cd -
  • Если Вы написали команду наполовину и вдруг передумали нажмите alt-# для того, чтобы добавить # к началу и отправьте команду как комментарий. Потом вы сможете вернуться к ней через историю.
  • Не забывайте использовать xargs (или parallel). Это очень мощная штука. Обратите внимание, что Вы можете контролировать количество команд на каждую строку, а так же параллельность. Если Вы не уверены, что делаете что-то правильно, начните с 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 для того, чтобы посмотреть открытые сокеты и файлы.
  • Используйте alias для того, чтобы алиасить часто используемые команды. Например, alias ll='ls -latr' создаст новый алиас ll.
  • В Баш скритах используйте set -x для того, чтобы дебажить аутпут. Используйте строгие режимы везде, где возможно. Используйте set -e для того, чтобы прекращать выполнение при ошибках. Используйте set -o pipefail для того, чтобы строго относится к ошибкам (это немного глубокая тема). Для более сложных скриптов так же используйте trap.
  • В Баш скриптах, подоболочки (subshells) – удобный способ группировать команды. Один из самых распространенных примеров – временно передвинуться в другую рабочую директорию, вот так:

  # do something in current dir
  (cd /some/other/dir && other-command)
  # continue in original dir

  • В Баше много типов пространства переменных. Проверить, существует ли переменная – ${name:?error message}. Например, если Баш-скрипту нужен всего один аргумент просто напишите input_file=${1:?usage: $0 input_file}. Арифметическая область видимости: i=$(( (i + 1) % 5 )). Последовательности: {1..10}. Обрезка строк: ${var%suffix} и ${var#prefix}. Например, если var=foo.pdf тогда echo ${var%.pdf}.txt выведет foo.txt.
  • Вывод любой команды можно обратить в файл через <(some command). Например, сравнение локального файла `/etc/hosts с удаленным:

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

  • Знайте про heredoc-синтаксис в Баше, работает он вот так cat <<EOF ....
  • В Баше перенаправляйте стандартный вывод, а так же стандартные ошибки вот так: some-command >logfile 2>&1. Зачастую для того, чтобы убедится, что команда не оставит открытым файл, привязав его к открытому терминалу считается хорошей практикой добавлять </dev/null.
  • Используйте man ascii для хорошей ASCII таблицы, с hex и десятичными значениями. Для информации по основным кодировкам полезны: man unicode, man utf-8, и man latin1.
  • Используйте screen или tmux для того, чтобы иметь несколько экранов в одном терминале, это особенно полезно, когда вы работаете с удаленным сервером, тогда Вы можете подключаться/отключаться от сессий. Более минималистичный подход для этого – использование dtach.
  • В SSH полезно знать как port tunnel с флагами -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 or fzf.
  • Для работы с файлами, список которых дала другая команда (например Git) используйте fpp (PathPicker).
  • Для того чтобы быстро поднять веб-сервер в текущей директории (и поддерикториях), который доступен для всех в вашей сети используйте:
    python -m SimpleHTTPServer 7777 (for port 7777 and Python 2) and python -m http.server 7777 (for port 7777 and Python 3).
  • Для того, чтобы выполнить определенную команду с привилегиями, используйте sudo (для рута) и sudo -u (для другого пользователя). Используйте su или sudo bash для того чтобы запустить шелл от имени этого пользователя. Используйте su - для того, чтобы симулировать свежий логин от рута или другого пользователя.

Процессинг файлов и информации


  • Для того, чтобы найти файл в текущей директории сделайте find. -iname '*something*'. Для того, чтобы искать файл по всей системе используйте locate something (но не забывайте, что updatedb мог еще не проиндексировать недавно созданные файлы).
  • Для основого поиска по содержимому файлов (более сложному, чем grep -r) используйте ag.
  • Для конвертации HTML в текст: lynx -dump -stdin
  • Для конвертации разных типов разметки (HTML, маркдаун и т.д.) попробуйте pandoc.
  • Если нужно работать с XML, есть старая но хорошая утилита – xmlstarlet.
  • Для работы с JSON используйте jq.
  • Для работы с Excel и CSV-файлами используйте csvkit (программа предоставляет команды in2csv, csvcut, csvjoin, csvgrep и т.д.)
  • Для работы с Amazon S3 удобно работать с s3cmd и s4cmd (последний работает быстрее). Для остальных сервисов Амазона используйте стандартный aws.
  • Знайте про sort и uniq, включая флаги -u и -d, смотрите примеры ниже. Еще гляньте на comm.
  • Знайте про cut, paste, и join для работы с текстовыми файлами. Многие люди используют cut забыв про join.
  • Знайте о wc: для подсчета переводов строк (-l), для символов – (-m), для слов – words (-w), для байтового подсчета – (-c).
  • Знайте про tee, для копирования в файл из stdin и stdout, что-то типа ls -al | tee file.txt.
  • Не забывайте, что Ваша локаль влияет на многие команды, включая порядки сортировки, сравнение и производительность. Многие дистрибутивы Linux автоматически выставляют LANG или любую другую переменную в подходящую для Вашего региона. Из-за этого результаты функций сортировки могут работать непредсказуемо. Рутины i18n могут значительно снизить производительность сортировок. В некоторых случаях можно полностью этого избегать (за исключением редких случаев), сортируя традиционно побайтово, для этого export LC_ALL=C
  • Знайте основы awk и sed для простых манипуляций с данными. Например, чтобы получить сумму всех чисел, которые находятся в третьей колонки текстового файла можно использовать awk '{ x += $3 } END { print x }'. Скорее всего, это раза в 3 быстрее и раза в 3 проще чем делать это в Питоне.
  • Чтобы заменить все нахождения подстроки в одном или нескольких файлах:

  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, для работы с человекочитаемыми числами используйте -h (например du -h). Знайте как работают ключи (-t и -k). В частности, не забывайте что вам нужно писать -k1,1 для того, чтобы отсортировать только первое поле; -k1 значит сортировка учитывая всю строчку. Так же стабильная сортировка может быть полезной (sort -s). Например для того, чтобы отсортировать самое важное по второму полю, а второстепенное по первому можно использовать sort -k1,1 | sort -s -k2,2`.
  • Если вам когда-нибудь придется написать код таба в терминале, например для сортировки по табу с флагом -t, используйте шорткат ctrl-v [Tab] или напишите $'\t'. Последнее лучше, потому что его можно скопировать.
  • Стандартные инструменты для патчинга исходников это diff и patch. Так же посмотрите на diffstat для просмотра статистики диффа. diff -r работает для по всей директории. Используйте diff -r tree1 tree2 | diffstat для полной сводки изменений.
  • Для бинарников используйте hd для простых hex-дампом и bvi для двоичного изменения бинарников.
  • strings (в связке grep или чем-то похожем) помогает найти строки в бинарниках.
  • Для того, чтобы посмотреть разницу в бинарниках (дельта кодирование) используйте xdelta3.
  • Для конвертирования кодировок используйте iconv. Для более сложных задач – uconv, он поддерживает некоторые сложные фичи Юникода. Например эта команда переводит строки из файла в нижний регистр и убирает ударения (кои бывают, например, в Испанском)

  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” value) – это память, которую держит ядро и эти значения являются частью free.
  • Дебаггинг Джавы – совсем другая рыбка, но некоторые манипуляции над виртуальной машиной Оракла или любой другой позволит вам использовать делать kill -3 <pid> и трассировать сводки стека и хипа (включая детали работы сборщика мусора, которые бывают очень полезными), и их можно дампнуть в stderr или логи.
  • Используйте mtr для лучшей трассировки, чтобы находить проблемы сети.
  • Для того, чтобы узнать почему диск полностью забит используйте ncdu, это сохраняет время по сравнению с тем же du -sh *.
  • Для того, чтобы узнать какой сокет или процесс использует интернет используйте iftop или nethogs.
  • ab, которая поставляется вместе в Апачем полезна для быстрой нетщательной проверки производительности веб-сервера. Для более серьезного лоад-тестинга используйте 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.
  • Узнайте какая у вас операционка через uname or uname -a (основная Unix-информация/информация о ядре) или lsb_release -a (информация о дистрибутиве).
  • Используйте dmesg когда что-то ведет себя совсем странно (например железо или драйвера).

В одну строчку


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

cat a b | sort | uniq > c        # c is a union b
cat a b | sort | uniq -d > c     # c is a intersect b
cat a b b | sort | uniq -u > c   # c is set difference a - b

  • Используйте grep. * для того, чтобы посмотреть содержимое всех файлов в директории, особенно послено когда у вас много конфигов типа /sys, /proc, /etc.
  • Получить сумму всех чисел, которые находятся в третьей колонки текстового файла. (Скорее всего, это раза в 3 быстрее и раза в 3 проще чем делать это в Питоне):

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

  • Если вам нужно посмотреть размеры и даты создания древа файлов используйте:

find . -type f -ls

Это почти как рекурсивная ls -l, но более читабельно чем ls -lR:
  • Используйте xargs (или parallel). Это очень мощная штука. Обратите внимание, что Вы можете контролировать количество команд на каждую строку, а так же параллельность. Если Вы не уверены, что делаете что-то правильно, начните с xargs echo. Еще -I{} – полезная штука. Примеры:

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

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

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

  • Запустите этот скрипт чтобы получить случайный совет из этой инструкции:

  function taocl() {
  curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-ru.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
}

Сложно, но полезно


  • expr: для выполнения арифметических и булевых операций, а так же регулярных выражений
  • m4: простенький макро-процессор
  • yes: вывод строки в бесконечном цикле
  • cal: классный календарь
  • env: для того, чтобы выполнить команду (полезно в Bash-скриптах)
  • printenv: print out environment variables (useful in debugging and scripts)
  • look: найти английские слова (или строки) в файле
  • cut:, paste и join: манипуляция данными
  • fmt: форматировка параграфов в тексте
  • pr: отформатировать текст в страницы/колонки
  • fold: (обернуть) ограничить длину строк в файле
  • column: форматировать текст в колонки или таблицы
  • expand: и unexpand: конвертация между табами и пробелами
  • nl: добавить номера строк
  • seq: вывести числа
  • bc: калькулятор
  • factor: возвести числа в степень
  • gpg: зашифровать и подписать файлы
  • toe: таблица терминалов terminfo с описанием
  • nc: дебаггинг сети и передачи данных
  • socat: переключатель сокетов и перенаправление tcp-портов (похоже на netcat)
  • slurm: визуализация трафика сети
  • dd: перенос информации между файлами и девайсами
  • file: узнать тип файла
  • tree: показать директории и сабдиректории в виде дерева; как ls, но рекурсивно
  • stat: информация о файле
  • tac: вывести файл наоборот (ласипан)
  • shuf: случайная выборка строк из файла
  • comm: построчно сравнить отсортированные файлы
  • pv: мониторинг прогресса прохождения информации через пайп
  • hd: и bvi: дамп и редактирование бинарников
  • strings: найти текст в бинарникх
  • tr: манипуляция с char (символьным типом)
  • iconv: и uconv: конвертация кодировок
  • split: и csplit: разбить файлы
  • sponge: прочитать весь инпут перед тем, как его записать, полезно когда читаешь из того же файла, куда записываешь, например вот так: grep -v something some-file | sponge some-file
  • units: конвертер, метры в келометры, версты в пяди (смотрите /usr/share/units/definitions.units)
  • 7z: архиватор с высокой степенью сжатия
  • ldd: показывает зависимости программы от системных библиотек
  • nm: получаем названия всех функций, которые определены в .o или .a
  • ab: бенчмаркинг веб-серверов
  • strace: дебаг системных вызовов
  • mtr: лучшей трассировка для дебаггинга сети
  • cssh: несколько терминалов в одном UI
  • rsync: синхронизация файлов и папок через SSH
  • wireshark: и tshark: перехват пакетов и дебаг сети
  • ngrep: grep для слоя сети (network layer)
  • host: и dig: узнать DNS
  • lsof: процессинг дискрипторов и информация о сокетах
  • dstat: полезная статистика системы
  • glances: высокоуровневая, многосистемная статистика
  • iostat: статистика CPU и использования жесткого диска
  • htop: улучшенная версия top
  • last: история логинов в систему
  • w: под каким пользователем вы сидите
  • id: информация о пользователе/группе
  • sar: история системной статистики
  • iftop: или nethogs: использование сети конкретным сокетом или процессом
  • ss: статистика сокетов
  • dmesg: ошибки бута и ошибки системы
  • hdparm: манипуляция с SATA/ATA
  • lsb_release: информация о дистрибутиве Linux
  • lsblk: cписок блочных устройств компьютера: древо ваших дисков и логических дисков
  • lshw:, lscpu, lspci, lsusb, dmidecode: информация о железе включая, CPU, BIOS, RAID, графику, девайсы, и т.д.
  • fortune:, ddate, и sl: хм, не знаю будут ли вам “полезны” веселые цитатки и поезда, пересекающие ваш терминал :)

MacOS only


Некоторые вещи релевантны только для Мака.
  • Системы управлением пакетами – brew (Homebrew) и port (MacPorts). Они могут быть использованы для того, чтобы установить большинство програм, упомянутых в этом документе.
  • Копируйте аутпут консольных программ в десктопные через pbcopy, и вставляйте инпут через pbpaste.
  • Для того, чтобы открыть файл или десктопную программу типа Finder используйте open, вот так open -a /Applications/Whatever.app.
  • Spotlight: Ищите файлы в консоле через mdfind и смотрите метадату (например EXIF информацию фотографий) через mdls.
  • Не забывайте, что MacOS основан на BSD Uni и многие команды (например ps, ls, tail, awk, sed) имеют некоторые небольшие различия с линуксовыми. Это обусловлено влянием UNIX System V и GNU Tools. Разницу можно заметить увидив заголовок “BSD General Commands Manual.” к манам программ. В некоторых случаях, на Мак можно поставить GNU-версии программ, например gawk и gsed. Когда пишите кроссплатформенные Bash-скрипты, старайтесь избегать команды, которые могут различаться (например, лучше используйте Python или perl), или тщательно все тестируйте.

Больше информации по теме


  • awesome-shell: Дополняемый список инструментов и ресурсов для командной строки.
  • Strict mode Для того, чтобы писать шелл-скрипты лучше.


Дисклеймер


За небольшим исключением, весь код написан так, что другие его смогут прочитать.
Кому много дано, с того много и спрашивается. Тот факт, что что-то может быть написано в Баше, вовсе не означает, что оно должно быть там написано. ;)

Лицензия


Creative Commons License
Оригинальная работа и перевод на русский язык распространяется под лицензией Creative Commons Attribution-ShareAlike 4.0 International License.

Комментарии (136)


  1. mureevms
    09.07.2015 09:18
    +2

    Вот так живешь, считаешь себя не плохим таким знатоком Linux, а тут раз и калькулятор в баше.
    А вообще, спасибо за статью, открыл несколько новых вещей для себя.


    1. steppefox
      09.07.2015 09:24

      Калькулятор в баше кстати необходимая вещь!)


      1. Ubuntovod
        09.07.2015 09:55

        Поначалу использовал python для подсчетов, пока не узнал про калькулятор. Сейчас смешно…


        1. Secessus
          09.07.2015 12:30
          +3

          Может, зря смеетесь. Я пробовал bc — не понравился.
          В итоге считаю на питоне. И конверсии в системы счисления есть и многое другое.
          разницы между

          echo 4*4|bc
          
          и
          echo 'print 4*4'|python
          

          не так и много, а при вызове repl — тем более.


          1. Halt
            09.07.2015 19:01
            +1

            Ubuntovod скорее имел в виду вот такую подстановку: i=$(( (i + 1) % 5 ))


          1. 4p4
            10.07.2015 13:30

            node -p 4*4


      1. raacer
        15.07.2015 15:23

        В KDE есть Alt+F2 — тоже довольно удобно использовать в т.ч. как калькулятор. Плюс еще и в том, что маленькое окошко висит поверх других окон, и цифры остаются на виду при переключении между окнами.


    1. cyberXndr
      09.07.2015 10:16
      +2

      bash: bc: command not found

      не в баше.


      1. Prototik
        09.07.2015 10:52
        +5

        В баше тоже есть, только маленький и неудобный :)

        prok@prok-nb ~ $ echo $((72*12345679))
        888888888


      1. kalterfive
        09.07.2015 11:04
        -1

        Ну так установите его…


      1. janekprostojanek
        09.07.2015 11:16

        Наверное потому, что Bash только интерпретатор команд, а внешние утилиты устанавливаются самостоятельно…


        1. cyberXndr
          09.07.2015 11:52
          +9

          Именно поэтому фраза «калькулятор в баше» является неверной.


      1. mureevms
        09.07.2015 13:28
        -2

        echo $SHELL
        /bin/bash
        bc
        bc 1.06.95
        ...
        


      1. saboteur_kiev
        10.07.2015 18:12

        $which bc
        /usr/bin/bc

        Это внешняя утилита. В Ubuntu ставится вместе с системой. Умеет много, свой внутренний язык. Например вычисляем Pi с точностью до 40 символов после запятой:

        echo «scale=40; 4*a(1)» | bc -l
        3.1415926535897932384626433832795028841968


    1. dcc0
      09.07.2015 11:41

      Важную команду забыли — chattr, с помощью нее можно сделать, например, файл неудаляемым. Еще несколько опций полезных наличествует.


      1. grossws
        09.07.2015 12:46

        Особенно она актуальна на btrfs, чтобы всяким логам ставить NO_COW))


    1. grumbler66rus
      09.07.2015 13:14
      +3

      Калькулятор не в bash. Это отдельная программа.


    1. kay
      10.07.2015 16:46

      я apcalc использую. выглядит следующим образом:

      calc
      C-style arbitrary precision calculator (version 2.12.4.4)
      Calc is open software. For license details type:  help copyright
      [Type "exit" to exit, or "help" for help.]
      
      ; 2^3
              8
      ;
      


  1. poxu
    09.07.2015 10:32
    +12

    Огромное спасибо за статью, форкнул репозиторий, нашёл неточности перевода, сделаю pull request.

    А теперь немного чистой, незамутнённой ненависти!

    В оригинальном тексте, как и во всех переводах, строки длиной по несколько метров!

    Если бы там был какой-нибудь plain text это можно было бы не простить, но хотя бы понять. Ну то есть автор хотел, чтобы ширина строки адаптировалась к ширине окна. Но там же маркдаун. Который при просмотре строки склеивает! Специально созданный в том числе для этого!

    Какого лешего! Как вышло так, что автор, рассказывающий об искусстве владения командной строкой отформатировал текст так, что при исправлении опечатки в одном слове, гит считает изменённым весь абзац целиком? Файл, внутри которого содержится рекомендация изучить и использовать vim, нельзя нормально редактировать с помощью этого текстового редактора, это как? Такого тонкого глумежа я не видал уже давно!


    1. saggid
      09.07.2015 11:03
      -5

      Банально, раз уж репозиторий располагается на GithHub'е, то, скорее всего, данный текст забивался в редакторе этого самого Github'а, в котором удобнее просто редактировать поток текста, не разбивая его самостоятельно на многие строки. И не во всех ситуациях ведь Vim теперь использовать, можно иногда и что-то другое)

      Насчёт того, что Git потом считает изменение в одной букве как изменение всего блока текста….Ну считает и считает, простите это ему) Это же не смертельно. Самое страшное, что может случиться из-за этого — это придётся 15-20 секунд потратить на ручное слияние одновременных исправлений от двух разных людей в одном блоке.


      1. poxu
        09.07.2015 11:27
        +4

        Самое страшное, что может случиться из-за этого — это придётся 15-20 секунд потратить на ручное слияние одновременных исправлений от двух разных людей в одном блоке.

        Да щас :). Если поправить 2 — 3 опечатке в строке и отправить пулл реквест автору, то просмотрщик диффов покажет только, что строка именена. Целиком. И дальше играем в игру — найди неизвестно сколько отличий в двух почти идентичных строках длиной с бассейн Амазонки и засеки сколько времени это займёт. Никак не 15 — 20 секунд :).

        Вот как раз линк на такой пулл реквест. github.com/olegberman/the-art-of-command-line/pull/3/files?diff=split. И это, кстати, исправления от одного человека. О разруливании конфликтов речи пока не идёт.


        1. Stalker_RED
          09.07.2015 15:15
          +4

          я, пожалуй, приложу картинку i.imgur.com/gds06ek.png


          1. poxu
            09.07.2015 17:31

            Ну да, я как раз об этом. Без специального вьюера тут не обойтись.


            1. Stalker_RED
              09.07.2015 18:35
              +2

              Так этих вьюверов не один и не два.
              i.imgur.com/uFdBGs7.png
              www.maketecheasier.com/file-comparison-tools-for-linux
              Никто не мешает использовать что-то более удобное, чем стандартный diff.


              1. poxu
                09.07.2015 19:08

                Есть некоторая разница между «не мешает» и «вынуждает». Кроме того, git add -p как делать в таком случае? Слать лесом часть git workflow из-за ничем не мотивированного наличия длинных строк?


                1. datacompboy
                  10.07.2015 12:58
                  +3

                  git diff --color-words


                  1. poxu
                    10.07.2015 13:58

                    Его можно как-то совместить с git add -p?


                    1. datacompboy
                      10.07.2015 16:32

                      1. poxu
                        10.07.2015 16:54

                        Гм. Спросим то же самое, но по другому.

                        После того, как пишешь git add -p, появляется окошко с редактором, в котором виден текущий чанк. И, если он слишком большой, есть возможность разбить текущий чанк на чанки поменьше. Если чанк представляет из себя очень длинную строку, можно будет разбить его на части?


                        1. datacompboy
                          10.07.2015 16:59

                          Нет. ЭТО не сплиттится.

                          Но по крайней мере сам чанк просмотреть можно без рвотного рефлекса.


                          1. poxu
                            10.07.2015 17:15

                            Печаль.

                            Спасибо за color-words кстати. Я про него был не в курсе.


                            1. datacompboy
                              10.07.2015 17:22

                              Я еще держу в .bash_aliases такое:
                              alias wd=«dwdiff --diff-input -c -P»
                              чтобы делать
                              diff -u a b | wd
                              (ну или аутпут других утилит, которые умеют только простой дифф печатать)


                1. Stalker_RED
                  10.07.2015 16:04

                  Можно же настроить
                  _http://jeetworks.org/setting-up-git-to-use-your-diff-viewer-or-editor-of-choice/


        1. saggid
          10.07.2015 19:15

          Я честно не понимаю, к чему весь этот сыр-бор, когда вам уже ведь дали картинку, как можно легко, в один клик, увидеть все различия между оригиналом и pull-request'ом:

          github.com/olegberman/the-art-of-command-line/pull/3/files?diff=split&short_path=2e086f3#diff-2e086f36ff961aa4d1079c87cde14d8d

          Всё там прекрасно видно, никаких дополнительных телодвижений не нужно. Ну и что тут дальше-то обсуждать?

          Понятно, что через консоль это может занять времени чуть больше, но зачем в данном случае вообще использовать консоль, когда все эти действия доступны на расстоянии одного клика в веб-интерфейсе Github'а? Это банально придирка к какой-то мелочи.

          И еще раз повторюсь: в редакторе Github'а намного удобнее пользоваться сплошными потоками текста, а не текстом, оформленным через ручную расстановку переносов. И в данной ситуации этот текст и гитхабовская репа просто используются как место для удобного хранения статьи с полезной информацией. Эту репу даже клонировать на свой компьютер нет особой нужды: просто возьмите и отредактируйте текст через редактор Гитхаба и прямо там же и оформите свой Pull-request, не усложняйте жизнь себе и другим) И воспринимайте это как обычный текст, а не как исходный код.


          1. WebConn
            13.07.2015 22:27
            +1

            В консоли же есть vimdiff…


    1. poxu
      09.07.2015 13:06

      Я отписался по теме длинных строк автору. Создал ишью. Вот оно github.com/jlevy/the-art-of-command-line/issues/167. Кому не лень и кто согласен с тем, что это мрак и ужас, поддержите просьбу, пожалуйста.


    1. itforge
      09.07.2015 14:21

      Создайте issue в оригинальном репозитории и опишите проблему. Возможно, автору покажутся разумными ваши доводы и он отформатирует текст в соответсвии с вашими пожеланиями.


      1. pfemidi
        09.07.2015 21:02
        +2

        Хоть убей не понимаю что может быть разумного в разбитии абзаца на отдельные строки вместо прямо таки напрашивающегося помещения его в виде отдельной строки «длиной с бассейн Амазонки». Все современные редакторы/вьюеры сами разбивают подобный текст исходя из ширины окна/экрана где они запущены. А вот в обратную сторону они строки не склеивают. Не знаю как кому, но лично мне весьма неприятно склеивать строки руками когда кто-то выложил столь «разумный» абзац, разбитый на строки по, скажем, 75 символов и который благодаря этому отображается как грустный столбик текста слева в одной трети ширины окна редактора/вьюера. По рукам бы автору такого текста, линейкой, чтобы не думал только о своём удобстве и о своей ширине экрана.

        Если текст это исходный код программы, то да, тут надо ограничивать длину исходя из текущего coding style. Но разбивать подобным образом обычный текст — увольте и избавьте от такого ужаса!


        1. poxu
          09.07.2015 22:17
          +5

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

          Кроме того, напомню, что системы контроля версий (по крайней мере git) считают изменения в файле построчно и при изменении одного символа в строке изменённой будет считаться вся строка. Смотреть изменения, сделанные в коммите, как unified diff становится очень неудобно. Исключать изменения, которые делать не нужно — тоже.

          Markdown это не обычный текст, это исходник, с которым предполагается работать с помощью системы контроля версий. Это многое меняет.


          1. Lol4t0
            10.07.2015 21:44
            +2

            Не очень понятно, что делать, если нужно добавить пару строк в середине абзаца — после этого конкретная строка уже перестанет умещаться в 75 символов — и чтобы поправить, надо будет все переформатировать


        1. zahardzhan
          10.07.2015 09:11
          +1

          «Грустный столбик слева в 75-85 букв шириной» — это так называемый книжный формат, которым является стандартом форматирования серьезных текстов уже сотни лет.


          1. pfemidi
            10.07.2015 09:25
            -1

            Я ничего не имею против бумажных книг обычного книжного формата. Но в данном случае «грустный столбик», расчитанный на формат А4 или даже А6, грустно висит в левом верхнем углу листа формата А0. Не совсем эстетично выглядит, ага?


            1. poxu
              10.07.2015 10:23

              Вы же не читаете документы в исходнике, правда?


              1. pfemidi
                10.07.2015 10:45

                zahardzhan судя по всему говорил не про именно исходник, а про абстрактный «грустный столбик слева в 75-85 букв шириной», являющийся книжным форматом. Вот я и ответил в данном случае не про исходник markdown, а про «грустный столбик слева в 75-85 букв шириной», который в окне 132x132 выглядит уныло.


  1. kalterfive
    09.07.2015 11:10
    +2

    Чтобы заменить все нахождения подстроки в одном или нескольких файлах

    Имхо, удобнее sed дёргать.
    $ cat file | sed 's/first/second/g'
    $ man sed
    


    Ожидал в статье увидеть ещё, что можно вйти с помощью ctrl-d. Открыл для себя nohup, была проблема с остановкой процессов из-за закрытия терминала.


    1. JIghtuse
      09.07.2015 11:27
      +2

      Имхо, удобнее sed дёргать.

      $ cat file | sed 's/first/second/g'

      Согласен. Только cat излишен.
      $ sed 's/first/second/g' file


      А вообще, не понимаю, чем это новомодное руководство лушче The Linux Command Line,The Command Line Crash Course, Learn Linux The Hard Way или какого-нибудь Bash Cheatsheet.


      1. simpleadmin
        09.07.2015 11:43
        +1

        Согласен. Только cat излишен.
        угу, а в связке с find вообще убойная сила
        find ./ -name '*.txt' -type f -exec sed -i '.bak' 's/first/second/g' {} \;
        


      1. janekprostojanek
        09.07.2015 12:01
        +2

        Я вот тоже хотел сказать, что всю статью (изначальную, а не труд переводчика) можно свести к четырем буквам.

        RTFM!


        1. Alexeyslav
          10.07.2015 09:00
          +1

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


      1. grossws
        09.07.2015 12:47

        Только тогда

        sed -i --follow-symlinks 's/first/second/g' files*


    1. JuriM
      09.07.2015 16:55

      Еще лучше sed -i.bak 's/first/second/g'


  1. janekprostojanek
    09.07.2015 11:12
    -2

    Выучите основы Баша. Просто возьмите и напечатайте man bash в терминале и хотя бы просмотрите его; он довольно просто читается и он не очень большой. Другие шеллы тоже могут быть хороши, но Баш – мощная программа и Баш всегда под рукой (использование исключительно zsh, fish и т.д., которые наверняка круто выглядят на Вашем ноуте во многом Вас ограничивает, например Вы не сможете использовать возможности этих шеллов на уже существующем сервере).

    На сервере может не быть и Bash, к примеру, в достаточно узкоспециализированной системе может быть в наличии только /bin/busybox sh.

    Выучите хотя бы один консольный редактор текста. Идеально Vim (vi), ведь у него нет конкурентов, когда вам нужно быстренько что-то подправить (даже если Вы постоянно сидите на Emacs/какой-нибудь тяжелой IDE или на каком-нибудь модном хипстерском редакторе)

    Серьезно? А я-то все время Nano пользуюсь…
    Вроде, не хипстерский и полегче, чем Vim, когда надо именно быстро что-то поправить.


    1. grossws
      09.07.2015 12:50

      Но для навигации по конфигам или правки кода/скриптов на удаленной машине vim куда удобнее. И обычно устанавливается одной командой при provisioning (тот же vim-minimal или elvis не люблю, не удобно оно).


    1. nickolaym
      09.07.2015 13:15
      +1

      Vim нужно изучить по двум причинам:
      — навигация в man и less сделана по мотивам vi
      — если он внезапно установлен как редактор по умолчанию (например, в git для ввода комментариев постфактум), то чтобы хотя бы знать, как из него выйти
      А так, nano вполне рулит.


      1. Kamikaze
        13.07.2015 18:44

        Шутка про «зашел в vi, не смог выйти» уже настолько стара, что кажется все, кто имеет хотя бы минимальную вероятность зайти в vi, как минимум как выйти знают.


        1. nickolaym
          13.07.2015 19:03
          +1

          Да щас. Сценарий для новичка:
          — поставил git на венду — само собой поставилоСЬ git shell (тюнингованный баш)
          — в командной строке, строго по инструкциям со стековерфлоу и т.п., накатил какую-нибудь репу
          — там же, в командной строке, по тем же инструкциям доброхотов, написал git log
          Вуаля, попал внутрь less.


          1. senia
            13.07.2015 20:37

            Основная проблема «выйти из vim» была не в том, как выйти корректно, а как выйти вообще.
            Когда новичок попадает в vim не в эмуляторе терминала, который легко закрыть вместе с окном, а в терминале. И при этом не знает как зайти в другой терминал. Представьте весь ужас человека, который потерял управление компьютером и от любых действий тот только пищит и наверняка всё портит!

            Другого компа с мануалами под рукой нет и единственный способ хоть как-то прекратить этот кошмар — выключить компьютер. И ведь выключали, иногда даже вырывая вилку из розетки.

            Сейчас таких проблем уже не встретить.


            1. nickolaym
              13.07.2015 20:43

              Раньше был ужас-ужас-ужас, а сейчас тьфу-чёрт.
              Закрыл терминал с неубиваемым лессом, и снова Win+R, cmd, cd my\long\way\to\tipperary, git log… OH SHI!

              (Для линукса сценарий такой же; разве что терминал открыть попроще).


              1. senia
                13.07.2015 20:49

                Как быстро человек додумается до start git log?


                1. nickolaym
                  13.07.2015 21:40

                  И у него будет два варианта:
                  если start git log быстро мелькнул и захлопнулся, — значит, надо сделать то же самое второй раз, но без start.

                  Нет уж, лучше один раз узнать про less, чем костылиться с виндовым терминалом.


              1. janekprostojanek
                16.07.2015 14:11
                +3

                Господи, что неубиваемого в less? Он закрывается стандартным нажатием кнопки q.


                1. vlivyur
                  17.07.2015 12:11
                  +1

                  Как и man и многие другие.


                  1. pfemidi
                    17.07.2015 13:46
                    +7

                    Давно, когда я только впервые столкнулся с *nix (это был SCO) я по-ошибке как-то умудрился запустить vi. И тогда меня просто поразило и убило что программа не выходит ни по нажатию ESC, ни меню не вызывается по по нажатию F9 или F10, не выходит так же ни через Altx-X, ни через Ctrl-Q, только пищит истерично. Я тогда ожидал что любую программу можно завершить какой-нибудь из этих клавиш/комбинаций, но vi меня обломал. Через минут пять безуспешных попыток выйти я просто напросто сделал power off/power on. Но не тут-то было! Когда я опять залогинился, то вылез этот самый vi. Он там то ли в nohup'е каком-то был, то ли ещё чего, но SCO честно его перезапускал после повторного логина — ведь vi не был в прошлый раз корректно завершён с точки зрения SCO, значит его надо запустить вновь. Через полдня мучений я просто напросто переставил целиком (sic!) весь SCO Unix, только так я смог «выйти» из vi. Сейчас это само собой звучит смешно, но тогда, в 1994-м году, мне было совсем не до смеха.


                    1. pfemidi
                      18.07.2015 14:54

                      Да, и когда я попробовал у него спросить что ему надо (ни про какие man'ы и про соседние консоли я тогда знать не знал), то никакой помощи по привычному нажатию F1 он тоже не выводил, только бибикал. В общем это было самое что ни на есть «Байтораздирающее зрелище».


        1. Alexeyslav
          14.07.2015 11:42
          +1

          Нифига. когда-то тоже зашел пришлось гуглить. Если еще раз зайду… придется долго вспоминать или снова гуглить. Старые не используемые знания имеют тенденцию вытесняться…


  1. YourChief
    09.07.2015 11:29
    +2

    Большинство утилит какой-то нераспространённый новодел не лучшего качества. На мой взгляд, так:

    -- iostat, sysstat, sar, glances, iftop
    ++ atop
    -- slurm
    ++ speedometer
    -- 7z
    ++ xz
    ++ pxz, pigz, pbzip2 - многопоточные компрессоры, на многопроцессорных системах творят магию моментально. совместимы с их однопоточными предшественниками xz, gz, bzip2
    


    1. poxu
      09.07.2015 11:31
      +1

      Поддерживаю pxz, pigz и pbzip2. Кстати, какой лучше, хотя бы чисто субъективно?


      1. YourChief
        09.07.2015 11:55

        pxz явный лидер. им и исходники на kernel.org жмут, и на практике он сжимал мне образ виртуалки (OpenVZ simfs) c 24GB до 1,62GB, базу 1С c 17GB до 3,8GB (на всех процессорах, максимальное сжатие).


        1. janekprostojanek
          09.07.2015 12:00

          Простите за флуд, ни фига себе


        1. poxu
          09.07.2015 12:30

          Сурово. Я тут образы дисков жал pbzip2. Получалось сэкономить несколько гигабайт из сотни что ли. Надо попробовать pxz, посмотреть чего получится.


          1. ValdikSS
            10.07.2015 00:17

            Вообще, лучше жмет, пожалуй, bzip2, но он СУПЕР медленный, xz гораздо быстрее при чуть худшем, но сопоставимом сжатии.


            1. istui
              11.07.2015 20:43
              +1

              у меня наоборот, лучше xz, особенно на логах


    1. janekprostojanek
      09.07.2015 11:34
      +5

      htop очень хороша утилита, мне нравится.

      Заголовок спойлера
      image


      1. Alkop
        09.07.2015 12:14

        Клёвые «часики». Никто не пробовал такое сделать?


    1. grossws
      09.07.2015 12:52

      iostat/iotop/iftop вполне удобны для того чтобы посмотреть здесь и сейчас, что творится. Хотя, почитав чуток статей, понимаешь, что тот же disk utilization или iowait мало что реально говорят о нагрузке на io.


      1. YourChief
        09.07.2015 13:25

        atop всё это показывает и может группировать процессы, что полезно когда имеется множество однородных воркеров. а также он хранит историю и её можно отмотать на нужный момент.


        1. grossws
          09.07.2015 14:05

          В этом плане, конечно. Хотя для всякой статистики по сетевым соединениям требует дополнительного модуля ядра, которого может не быть в репозиториях.


    1. kalterfive
      12.07.2015 12:19
      +1

      Не увидел в первых двух строчках htop. Имхо, за ++.


  1. Secessus
    09.07.2015 12:41
    +1

    Спасибо за труд и популяризацию unix и bash.

    ~$ m4
    The program 'm4' is currently not installed. You can install it by typing:
    sudo apt-get install m4
    ~$ pv
    The program 'pv' is currently not installed. You can install it by typing:
    sudo apt-get install pv
    

    Я так понимаю, где-то половины из описанного в linux не стоит «из коробки».

    Тогда логичнее описать coreutils, так как
    The GNU Core Utilities are the basic file, shell and text manipulation utilities of the GNU operating system.
    These are the core utilities which are expected to exist on every operating system.
    (отсюда)

    К примеру, в тексте ни слова о pwd и basename, а они, порой, гораздо важнее в скриптах, чем, например, factor, и входят в те самые coreutils.


    1. ValdikSS
      10.07.2015 00:19
      +1

      Меня больше удивляет, сколько людей не знает про getent и грепают /etc/passwd и /etc/group


      1. grossws
        10.07.2015 00:52

        Ещё веселее докер, который их парсит принципиально (чтобы не завязываться на glibc), что приводит к тому, что не видится группа docker, которая раздаётся централизовано (например, через sssd+ldap). Но issues libcontainer закрыли, соответственно в кэше гугла содержит только сам тикет, но не переписку. Ещё кусок обсуждения в PR.


      1. raacer
        15.07.2015 15:44

        Простите, а как это намазывается? Говорит «Неизвестная база данных» :)


        1. ValdikSS
          15.07.2015 15:46

          % getent passwd valdikss
          valdikss:x:1000:100::/home/valdikss:/usr/bin/zsh

          Создать группу, если ее не существует:
          % getent group nonexistent || groupadd nonexistent


          1. raacer
            15.07.2015 15:56

            Спасибо большое за пояснение! А то я ступил и полный путь указал ))

            Скажите, в чем для Вас преимущество этой команды перед использованием grep? Можно грепнуть «www» и найти «www-data», например, а getent этого не позволяет. Да и лишнюю команду в голове держать — зачем?


            1. ValdikSS
              15.07.2015 16:03
              +3

              grossws выше хороший пример привел — совершенно не обязательно пользователь должен быть локальный, есть еще тот же LDAP. Записи о пользователе в /etc/passwd не будет, но использовать-то его можно.

              Ну, или представьте, что у вас пользователь называется home. Чтобы избежать совпадение grep по домашнему пути, который, как правило, начинается с /home/, вам уже нужно будет писать regexp.


      1. JIghtuse
        16.07.2015 06:38

        Туда же можно добавить getmntent (3). Это функция библиотеки, но утилиту из неё сделать несложно. Больше не придётся грепать/парсить руками fstab/mtab.


        1. grossws
          16.07.2015 07:12

          getent в общем-то и построен вокруг getgrent/getsgent/getpwent/etc, так что могли бы в glibc-common и такое добавить


          1. JIghtuse
            16.07.2015 09:30

            Идея хорошая, нужно будет попробовать на досуге патч отправить.


  1. grossws
    09.07.2015 12:44
    +1

    Долго читал оригинал на github'е, т. к. в процессе отправил 6 PR.


  1. grumbler66rus
    09.07.2015 13:21

    Чтобы заменить все нахождения подстроки в одном или нескольких файлах:
    perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt


    Проще и быстрее
    sed -i 's/old-string/new-string/g' my-files-*.txt

    Опечатки, которые бросились в глаза:
    аббривиатур
    директории (и поддерикториях)

    Насчёт vim автор тоже погорячился. Во-первых, он есть не везде. Во-вторых, vi и vim требуют искейпа для выхода из режима редактирования. Поэтому самый универсальный редактор — ed, с ним можно работать в терминалах без клавиши ESC.


    1. Lol4t0
      09.07.2015 16:52
      +2

      Во-вторых, vi и vim требуют искейпа для выхода из режима редактирования.


    1. saboteur_kiev
      10.07.2015 01:12
      -1

      зачем запускать монстр sed, если есть tr?


      1. grossws
        10.07.2015 02:49

        man tr


      1. grumbler66rus
        10.07.2015 07:20

        RTFM!

        [root@host-7 ~]# echo abcdedca | sed s/cde/PUP/
        abPUPdca
        [root@host-7 ~]# echo abcdedca | tr cde PUP
        abPUPUPa


        1. saboteur_kiev
          10.07.2015 18:36
          +1

          Спасибо… Был глуп и необразован :(


  1. potan
    09.07.2015 13:31
    -5

    Когда-то я очень любил bash. Но потом меня загнали вод винды, и я понял, что PowerShell круче, хотя completition в нем не слишком удобный.
    Жаль, что он под Unix не портирован…


    1. janekprostojanek
      09.07.2015 13:41

      Эм… а разве PowerShell не создавался изначально как этакая копия мощной командной строки Unix? Когда у них был только убогий дос… А потом внезапно появился PowerShell, когда стало ясно, что одними оконными свистопердами ни одному админу не обойтись. Понятно, что в чем-то он круче, т.к. возможно создавался с учетом успешных примеров


      1. potan
        09.07.2015 14:05
        +1

        Это не копия, а совсем другой язык. Общие разве что каналы (pipe), и то в bash по ним передается сырые данные, как правило интерпретируемые как текст, а в PowerShell — объекты.
        Но терминал и completition в нем неудобны.


    1. grumbler66rus
      10.07.2015 07:24
      -1

      В Powershell встроены скриптовые вызовы некоторых системных функций, не более того. В качестве универсального языка программирования он практически неприменим.
      unix shell же является классическим функциональным языком программирования, bash — его развитие (расширение).


      1. potan
        10.07.2015 13:48
        -2

        Конвеер в PowerShell более развит, чем в bash. Работа со строками проще. Синтаксис чище.
        Проигрывает он только в интерактивности.


        1. saboteur_kiev
          10.07.2015 18:25
          +3

          Это не так, потому что смотреть нужно не в сами команды конвейера, а в то, как устроена сама система. В Linux практически каждое устройство, каждый процесс имеет абстракцию в виде имени файла на виртуальной файловой системе, из-за чего перенаправлять в именованные потоки и дескрипторы можно ГОРАЗДО шире, чем в виндовсе будет возможно даже в обозримом будущем.
          По поводу удобства синтаксиса нужно смотреть на возможности. Например те, кто думает, что gzip странный, потому что не может сжать два файла, возможно не понимают в чем преимущество потокового архиватора.


          1. potan
            10.07.2015 18:53

            В PowerShell в конвеер объединяются функции, которые получают потоки как аргументы. Вместо глобальных именованных каналов используются локальные переменные.


            1. saboteur_kiev
              10.07.2015 18:58

              Как echo Hello перенаправить в USB устройство в Windows?
              Как echo Hello перенаправить в bash пользователя, который подключился удаленно в Windows?

              Я же вам сказал, что преимущество перенаправлений в Линукс заключается в том, что сама система спроектирована так, что перенаправление возможно практически между любой сущностью системы, включая процессы и устройства, что расширяет возможности того, что можно автоматизировать на коленке, в командной строке, одной-двумя командами, без создания 100-строчного скрипта с объявлением классов, объектов и т.д., причем не уверен что с классами и объектами можно будет выполнить два примера, которые я указал выше.


              1. datacompboy
                10.07.2015 19:27

                Как «echo Hello» перенаправить на TCP порт по IPv6?

                Через спец.тулзы перенаправление куда угодно работает где угодно — была бы связка двух тулз.


                1. YourChief
                  11.07.2015 14:03
                  +1

                  без тулз.

                  echo Hello > /dev/tcp/2a03:f480:1:13::c0/12345
                  


                  1. datacompboy
                    11.07.2015 14:22

                    это баш-экстеншен. (кстати, спасибо, иногда удобно).
                    то есть в системе как раз /dev/tcp отсутствует.


  1. nickolaym
    09.07.2015 13:41
    +7

    Галопом по европам, но хозяйке на заметку. Спасибо!

    А перевод, конечно, грязноват, и советы местами странноваты.

    m4 — «простенький» макропроцессор :)))
    Надо бы, конечно, освоить, а то всё awk (да python в тяжёлых случаях).
    Кстати, awk — в отличие от m4 — из коробки. А штука-то достаточно мощная и полезная…

    Перед тем, как давать совет «man anything», нужно давать совет «как выйти из мана». Это, всё-таки, недо-vi.

    За «инпут» и «аутпут» — зла не хватает. Не поленился транскрибировать, а на перевод уже сил не осталось, или это и есть перевод?
    *(надевает красную повязку с чёрной буквой G на белом круге)*


  1. nfubh
    09.07.2015 15:33

    alt-* расширяет глоб.??

    «Выполняет подстановку в шаблон»? Правда, я так и не понял, как оно работает.

    А документ потрясающий, спасибо!


    1. spmbt
      09.07.2015 19:27

      … Например, alt-. бежит по предыдущим аргументам команды, а alt-* расширяет глоб.??
      Тут и в источнике почему-то ошиблись (2 раза). Разбор манов вот о чём говорит:

      superuser.com/questions/215950/how-to-expand-on-bash-command-line
      ss64.com/bash/syntax-keyboard.html
      en.wikipedia.org/wiki/Glob_%28programming%29

      Т.е. в итоге эту фразу я переписал на (прочитать начисто статью со всеми 10050 правками):
      Например, alt-. вставляет последний аргумент предыдущей команды, а ctrl-x * разворачивает глоб.

      И в оригинале:
      ...For example **alt-.** inserts last argument of previous command, and **ctrl-x *** [expands a glob](...)
      (правда, проверить не на чем). Тут, если совсем точно, то «ctrl-x *» надо ещё настроить в ~/.inputrc (по первой ссылке).


      1. nfubh
        10.07.2015 11:13

        Проверил, работает! В дефолтной конфигурации выглядит так:

        $ bind -q glob-expand-word
        glob-expand-word can be invoked via "\C-x*".
        
        $ bind -q insert-completions
        insert-completions can be invoked via "\M-*".
        


        Т.е. Ctrl-X + * и Alt-*, соответственно.


  1. yktoo
    09.07.2015 16:33
    +3

    Я б добавил ещё watch, позволяющий периодически (по умолчанию — раз в 2 с) выполнять любую команду и отображать её вывод в полноэкранном режиме, например:

    watch ps xw
    


    1. JuriM
      09.07.2015 16:58

      Про lsof тоже забыли (хотя вру — указан там lsof)


  1. berman Автор
    09.07.2015 17:17
    +1

    Всем спасибо за пулл-реквесты, советы по улучшению и помощь! PR'ы все просмотрю сегодня после работы (у нас со многими из вас очень разный часовой пояс).

    Пара моментов: не нужно писать мне в личку забыли X, лучше использовать Y. Это – результат коллективного труда и вы можете сами влиять на материал как хотите. Только если добавляете новые команды, пожалуйста добавляйте их в английскую версию (желательно перед этим открыть тикет в оригинальном репе и посмотреть, согласно ли сообщество с вами). Из английской версии переводчики переведут во все остальные. Если в английскую отправлять не хотите можете открывать тикет в моем форке на русском, и я переведу этот тикет на английский и переотправлю его Джошу в оригинальный реп (опять-же, только если ваше дополнение того стоит).

    Если же вы вносите изменения именно в перевод (исправление опечаток, изменения формулировок, то не важно куда вы отправляете PR (мне в форк или Джошу в оригинальный реп). У меня уже куча пулл-реквестов, всем огромное спасибо. Русскоязычному сообществу нужно плотнее интегрироваться в Github.

    Кто-то заметил проблему длинных строк, она решабельна, но тогда скорее всего сломается git diff, поэтому пока что советую в редакторе, в котором вы редактируете маркдаун включить перенос строк.

    Кстати, почему на Хабре до сих пор нет маркдауна? Местная разметка — убогий отстой. OMG, Emoji тут тоже не поддерживаются


    1. berman Автор
      09.07.2015 17:22

      Уточню насчет того что сказал

      > не нужно писать мне в личку забыли X, лучше использовать Y.

      Это только потому, что после такого сообщения мне самому придется попробовать X и Y и сравнить с тем что есть и оценить, достойны ли они быть в подборке. В случае, когда вы это делаете напрямую в Github, кто-то в сообществе наверняка уже пробовал X и Y и интегрировать дополнения тогда мы сможем намного быстрее. Мне конечно интересно попробовать ваши XY, но последнее время работа занимает столько времени, что становится страшного от того, что ни на что другое времени нет


    1. poxu
      10.07.2015 10:28

      Кто-то заметил проблему длинных строк, она решабельна, но тогда скорее всего сломается git diff, поэтому пока что советую в редакторе, в котором вы редактируете маркдаун включить перенос строк.

      Я создал ишью в оригинальном репе по этому поводу. Надеюсь автор что-нибудь с этим сделает.
      Кстати, почему на Хабре до сих пор нет маркдауна? Местная разметка — убогий отстой. OMG, Emoji тут тоже не поддерживаются

      Пятьдесят раз да! Тысячу раз да! Вы, кстати, как статьи пишете? Я пишу в маркдауне, потом конвертирую в html, вставляю в хабраредактор и правлю.


      1. grossws
        10.07.2015 13:12

        Аналогично, md -> html и небольшой постпроцессинг (для кусков кода, картинок и т. п.). Но мой старый опрос (за который меня ещё и чуток слили) показал, что большинству достаточно html и остальное нафиг не сдалось.


  1. amarao
    09.07.2015 18:39

    (xargs) Еще -I{} – полезная штука.

    Это глупость, которую с find'а притащили. Зачем лишние символы печатать? Можно использовать любой символ, я обычно использую I капсом, чтобы меньше думать и быстрее печатать.

    ls -1 |xargs -I I echo The I was here.


  1. dmrt
    09.07.2015 20:58

    Недавно развлекался в баше раскрашивая себе PS1 в зависимости например от того в каком проекте находишься, в какой ветке репозитория и в какой папке.


    1. berman Автор
      09.07.2015 21:21
      +2

      Развлекаться еще можно так:

      rand=$(jot -r 1 1 100); wget -qO- http://shortiki.com/export/api.php\?format\=json\&type\=top\&amount\=100 | jq ".[$rand].content" | say --voice=Milena -i
      


      (на Маке, должны быть установлены jot, jq, wget)


      1. dmrt
        09.07.2015 22:01
        -1

        Класс, работает.
        Не знал что на маке есть такая классная команда say и куча голосов и для русского языка в том числе.
        Макбук — лучший ноутбук (со старым добрым диском HD)


        1. stychos
          10.07.2015 14:07

          А почему HD хорош?


          1. dmrt
            10.07.2015 14:11

            Дольше прослужит.
            Да и данная модель подешевле, ретину не видел, может не всем она по душе и есть еще Ethernet порт.


            1. olegkrasnov
              10.07.2015 16:46
              +2

              Кто поработал на SSD, вряд ли вернётся на HDD. Это как с порша обратно в запорожец.


            1. stychos
              10.07.2015 17:25
              +1

              Что-то я либо неверно прочёл, либо неверно понял.
              HD — это модель мака, или речь о HDD? Просто в силу нищебродства, маком никогда не обладал, потому довольствуюсь хакинтошем на асусовом x550vb (чем весьма доволен). Так вот, с тех пор как заменил родной hdd на ssd, больше года не могу нарадоваться, насколько он лучше работает. Если речь о том, что ssd умирают быстрее, то моя точка зрения в том, что это миф, ибо харды у меня ломались быстрее-выше-сильнее, а тут за год интенсивного использования ещё все 100 % remaining life. Ну а если речь именно о самих ноутбуках, то извините за то, что неверно понял.


              1. dmrt
                10.07.2015 20:05

                Да, я имел ввиду HDD, извиняюсь, за сокращение такое.
                Ну что же, не знал что SSD такие живучие. Спасибо за инфу. Но правда они все же дороже.


                1. stychos
                  10.07.2015 20:37

                  Я живу в одной маленькой, гордой и непризнанной стране, и работаю на бюджет. Потому отдавать половину зарплаты за SSD было, конечно, очень неохота. Но оно того стоит! В среднем, SSD сейчас стоит как HDD лет семь назад, два гигабайта за доллар.


  1. saboteur_kiev
    09.07.2015 23:11
    +1

    Спасибо, много полезного материала, собранного в кучку.
    Но есть непроверенные или нераскрытые до конца вещи, которые в такой краткой подаче могут только запутать. Некоторые из них:

    > Будьте знакомы с работой с процессами в Bash: &, ctrl-z, ctrl-c, jobs, fg, bg, kill, и т.д.
    Процессы (processes) и задачи (tasks) — разные вещи.
    Эти команды (fg, bg, jobs) управляют именно задачами, и относятся к работе самой оболочки. Нужно не путать задачи и процессы. То есть любая задача — процесс, но не любой процесс — задача.

    > найте про heredoc-синтаксис в Баше, работает он вот так cat <<EOF…
    Он работает не совсем так. Вместо EOF правильно писать delimiter, потому что тут может быть любое сочетание букв (EOF — это просто привычная аббревиатура). После чего можно ввести многострочный текст, а закончить его опять delimiter в пустой строке. Правильный пример:
    cat << delimiter


    delimiter

    > В Баше много типов пространства переменных. Проверить, существует ли переменная – ${name:?error message}.

    конструкция ${variablename:[cmd][text]} имеет четыре [cmd]: -=+?
    — просто вывести наш [text], если variablename==null
    = присвоить variablename значение [text], если variablename==null и вывести variablename
    + вывести [text], если variablename != null
    ? вернуть ошибку и вывести [text]

    Просто проверить существует ли переменная, это [ -n ${var} ]. То есть не раскрыта конкретная тема, почему именно {$name:?error}, которая на самом деле не просто проверит существует ли переменная, но еще и выдаст ошибку (и соответственно завершит наш скрипт).

    > Для того, чтобы выполнить определенную команду с привилегиями, используйте sudo (для рута) и sudo -u (для другого пользователя). Используйте su или sudo bash для того чтобы запустить шелл от имени этого пользователя. Используйте su — для того, чтобы симулировать свежий логин от рута или другого пользователя.

    su -u не полноценно симулирует свежий логин от другого юзера. Во многих случаях могут остаться мусорные переменные окружения. Ну и нужно правильно настроить sudoers, чтобы иметь возможность использовать sudo. Тут вообще тема не очень раскрыта. Например не упомянуто, что некорректно логиниться от root, лучше вообще иметь пользователя root с пустым паролем и запретить логин с пустым паролем. А права суперпользователя наследовать через su/sudo — это современная практика.

    > Сложно, но полезно
    Было бы неплохо этот список отсортировать по алфавиту, для удобства.


    1. grumbler66rus
      10.07.2015 07:29
      +1

      Например не упомянуто, что некорректно логиниться от root, лучше вообще иметь пользователя root с пустым паролем и запретить логин с пустым паролем. А права суперпользователя наследовать через su/sudo — это современная практика.


      Проще и надёжнее в поле пароля (в базе паролей) указать символ звёздочки.


  1. kiba
    10.07.2015 10:40

    случайный совет, альтернативная реализация через xmllint и html2text (у меня с xmlstarlet не работало — были проблемы с кодировкой):

    function taocl() {
            curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-ru.md |
            pandoc -f markdown -t html -s |
            xmllint --format --recover --dropdtd --html --xpath "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" - 2>/dev/null |
            html2text -utf8 |
            fmt -80
    }


  1. 4p4
    10.07.2015 13:37
    -3

    Когда создателя Баша спосили, как вы видите развитие Bash, он сказал «хочу чтобы он поскорее перестал использоваться, давно пора написать, что-то отвечающее современным реалиям».


  1. kay
    10.07.2015 16:18

    Для того, чтобы получить более наглядный вывод json, можно использовать:

    cat json.json | python -mjson.tool
    


  1. kay
    10.07.2015 16:35

    Просмотр environment уже запущенного процесса:

    cat /proc/`pidof someapp`/environ | tr '\0' '\n'
    


  1. kay
    10.07.2015 16:41

    Конвертирование единииц исчисления байты, мегабайты, мибибайты и прочее:

    numfmt --to=iec-i ...
    


  1. il--ya
    14.07.2015 17:34

    Извините, лень письмо писать:
    «file glob expansion with * (and perhaps? and {…}),» — явно недопереведено
    «безпарольной аунтефикации» — беспарольная аутентификация (а лучше «проверка подлинности»)


  1. Himalaya_Irbis
    14.07.2015 20:34

    i7z надо бы добавить


  1. madkite
    31.07.2015 21:24

    ctrl-u для того, что бы удалить команду полностью
    ctrl-k для того, чтобы прыгнуть к концу строки
    По умолчанию у bash-а эмаксовские keybindings, ctrl+u удаляет до начала строки, ctrl-k удаляет до конца строки, а прыгнуть к концу строки — ctrl+e.

    Идеально Vim (vi), ведь у него нет конкурентов, когда вам нужно быстренько что-то подправить (даже если Вы постоянно сидите на Emacs...
    Не хочу разводить holy war, но справедливости ради стоит отметить, что так было лет 20 назад. На текущий момент даже GNU Emacs довольно лёгкий (по сравнению с джавовскими ide), консольная версия стартует моментально и для быстрого редактирования одной строчки подходит не хуже vim-а, который сейчас наворотили так, что весит он побольше многих Emacs-ов. К тому же GNU Emacs-ом мир не ограничивается, openbsd-шный mg ещё легче.