И снова приглашаем погрузиться в команды GNU/Linux, которые удобно использовать разработчику для решения повседневных задач. Напоминаем, подборка ориентирована на тех, кто не хочет залезать глубоко в систему, но по работе вынужден иногда ходить на Linux-сервер. 

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

Статья написана по мотивам ИТ-посиделки, где мы обменивались полезными лайфхаками.

XKCD: 1168
XKCD: 1168

Команды bash

По умолчанию в большинстве дистрибутивов Linux сейчас используется оболочка bash. У нее есть много интересных возможностей. 

Не все знают, но у bash есть автодополнение - можно начать писать имя команды и если она есть где-то в переменной path, bash автоматически ее дополнит. Применить автодополнение можно клавишей TAB. Правила автодополнения на самом деле чуть более сложные и их можно редактировать самостоятельно. Для многих распространённых команд такие правила уже созданы и, скорее всего, уже установлены в вашем дистрибутиве. 

Очистить консоль от предыдущего хлама, который там накопился можно командой

clear

Альтернативная команда позволяет также вернуть клиентскую часть терминала в первоначальный режим (если внезапно все сломалось):

reset

Просматривать историю команд, набранных на данной машине под данным пользователем, можно при помощи

history

Есть несколько полезных переменных, которые настраивают поведение этой команды:

  • HISTCONTROL - по умолчанию команды, которые начинаются с пробела, в  history не записываются; данная переменная позволяет это отключить;.

  • HISTIGNORE - позволяет задать одну или несколько масок, по которым определенные команды в history заноситься не будут;

  • HISTTIMEFORMAT - позволяет записывать в history время и дату, когда набиралась определенная команда; мы используем ее на серверах;

  • HISTSIZE / HISTFILESIZE - позволяют контролировать размер history; по умолчанию он обычно равен 1000.

Поиск по history осуществляется при помощи сочетания Ctrl+R. После его нажатия можно начать набирать команду и bash автоматически подставит ее из history. Отредактировать команду можно при помощи правой или левой курсорной клавиши. Enter отправляет команду на выполнение. Выход из режима поиска - Ctrl+G.

Чтобы повторить последние две-три команды, не обязательно пользоваться поиском. По history можно перемещаться клавишами вверх и вниз, последовательно проматывая команды. Однако глубоко в history таким способом забираться неудобно.

Дополнительные полезные опции команды:

  • !! - запуск последней команды из history;

  • !N - запуск команды N из history;

  • !* - подстановка аргументов последней команды history, например если вам в нескольких командах надо использовать один и тот же файл в качестве аргумента.

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

  • > file - перенаправление STDOUT в файл, при этом файл перезаписывается или создается; например, перенаправляем вывод команды в файл: history > ./222;

  • >> file - аналогично, но без перезаписи;

  • &>>/&> file - перенаправляет и STDERR (сообщения об ошибках) и STDOUT в файл; эти варианты используются, если команда может выдать какие-то ошибки.

Перенаправить вывод одной команды в качестве аргумента другой можно при помощи следующей конструкции:

command1 | command2

Например, можно сделать: 

tail -t access.log | grep 502

Эта команда откроет access.log (предположим, это лог nginx) и в нем выполнит поиск по тексту 502. Конструкция позволяет строить очень длинные пайплайны.

Последовательно запускать несколько команд можно с помощью других конструкций. Здесь вариантов больше (приведены только наиболее часто используемые):

cmd1 && cmd2

cmd1; cmd2

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

Полезные шорткаты для работы с bash: https://www.tecmint.com/linux-command-line-bash-shortcut-keys/ 

Bash aliases

Одна из часто используемых фишек bash - алиасы - возможность назначить команде с определенными параметрами или аргументами собственное имя. Некоторое количество в bash уже есть из коробки, например упомянутый в первой части ll для ls -l. На самом деле ls сам является алиасом (выводит список файлов с параметром -color). Дополнительные алиасы можно создавать самостоятельно или устанавливать из других пакетов.

Отличный набор алиасов для работы с git: https://github.com/Bash-it/bash-it/blob/master/aliases/available/git.aliases.bash. По сути это универсальный комбайн для bash. Помимо алиасов там есть много полезных функций, например для работы с гитом. В частности, если мы проваливаемся в директорию, внутри которой находится скачанный репозиторий Git, нам выводится дополнительная информация - ветка, в которой мы сейчас находимся, есть ли в ней изменения и какие, добавлены ли они. Этот функционал визуально упрощает работу с Git.

Для установки копируем в домашнюю директорию, в .bashrc добавляем строки:

if [ -f ~/git.aliases.bash ]; then
     . ~/git.aliases.bash
fi

Какие алиасы уже есть в системе, можно посмотреть в директории /etc/profile.d.

Работа с сетью в стиле old-school

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

В будущем разработчики грозятся и вовсе их выпилить.

В первую очередь - это старый добрый netstat

Наиболее часто используемые ключи:

  • tunlp [seconds] - выводит список открытых TCP/UDP портов в системе и процессов, которые их слушают (значение каждого из символов можно посмотреть в man);

  • es [seconds] - выводит краткую статистику по Ethernet и TCP; здесь можно посмотреть все, что происходит в сетке - ошибки и прочее; это удобно в ходе диагностики сети;

  • on(t,u)(p) [seconds] - открытые соединения вместе с сокетами или без них;

  • rn / route -n - пара ключей, которая помогает управлять маршрутами - просматривать таблицу маршрутизации.

У netstat существует аналог с динамической визуализацией. Он помогает наблюдать в режиме реального времени, что происходит на сетевых интерфейсах, - какие соединения, сколько трафика прошло в рамках каждого соединения и т.п.

iptraf-ng

Раньше эта утилита называлась iptraf2. Кстати, UDP она тоже отслеживает.

На серверах эта утилита есть не всегда, но если она присутствует - рекомендуем.

Просматривать конфигурацию сетевых интерфейсов помогает старый добрый

ifconfig

Он выводит статистику по IP-адресам. По работе здесь нас обычно интересуют ошибки, дропы и прочая нечисть, которая происходит на сетевых интерфейсах. В современные дистрибутивы ifconfig уже не входит. Его нужно доустанавливать вместе с netstat из пакета net tools.

Посмотреть не IP-, а MAC-адреса помогает

arp

Особенно она полезна, если есть какая-то старая техника с дублирующимися MAC-адресами.

Проверить открытый порт на определенной машине можно командами

nc <ip> <port>

или 

telnet ip port

При этом выйти из telnet можно при помощи Ctrl+] или quit.

Работа с сетью при помощи iproute2

Теперь поговорим о более современном наборе утилит - iproute2. Это универсальный комбайн для управления сетевой подсистемой ядра. У него три основные команды:

  • ip

  • ss 

  • tc

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

ip addr

ip link

Это аналоги ifconfig - просмотр и модификация сетевых настроек, но несколько в другом виде.

ip route

Это аналог route и netstat.

ip neigh

Параметр neigh - это сокращение от neighbors, т.е. управление таблицей ARP (аналог arp).

ip -s 

ss

Это аналоги netstat. Выводит ту же статистику по соединениям, но в ней есть чуть больше информации. В частности, 

ss -ontup

Показывает открытые соединения - сколько пакетов было передано и т.д.

ss -tunlp

Выводит открытые порты TCP/UDP и процессы, которые их слушают.

Кстати, ip поддерживает cisco-like интерфейс, т.е. можно указывать сокращенное написание параметров (например: ip a), как на коммутаторах Cisco.

Хорошая шпаргалка от RedHat по работе с сетью: https://access.redhat.com/sites/default/files/attachments/rh_ip_command_cheatsheet_1214_jcs_print.pdf. В этом документе есть примеры, как настраивать и траблшутить.

Использование curl для диагностики

Мы используем curl для диагностики проблем, например с сайтом. Здесь приведем некоторые полезные варианты.

curl -v --resolve example.com:443:127.0.0.1 http://example.com 

Это проверка работоспособности сайта, не затрагивая hosts или DNS. Бывает полезно, если, например вы развернули у себя на виртуалке локальную копию движка и хотите проверить, как он работает. Самый банальный способ (и наиболее часто используемый) - прописать в hosts свой айпишник и имя домена. Но можно этого и не делать, используя curl. Используя параметр resolve, вы можете указывать доменное имя, порт и IP.

Также можно создать текстовый файл format.txt, в котором пропишем формат вывода и посмотреть, как curl обработает сетевое соединение. 

curl -w “@format.txt” -o /dev/null -s “https://google.com”

Формат в файле:

time_namelookup:  %{time_namelookup}s\n
time_connect:  %{time_connect}s\n
time_appconnect:  %{time_appconnect}s\n
time_pretransfer:  %{time_pretransfer}s\n
time_redirect:  %{time_redirect}s\n
time_starttransfer:  %{time_starttransfer}s\n
\n
time_total:  %{time_total}s\n

В таком варианте видно, сколько времени заняла работа с DNS, сколько ушло на само соединение, сколько было редиректов и т.п.

Работа с ssh

Эта часть относится не только к тем, кто использует Linux, но и ко всем остальным обладателям клиентов ssh (они есть под Mac и Windows, хотя в некоторых деталях их работа может отличаться).

ssh считается швейцарским ножом по работе с удаленными серверами.

Не все знают, что можно написать просто 

ssh <адрес сервера> <команда>

и она будет выполнена. То есть ssh можно использовать в неинтерактивном режиме. Можно писать пайпы, выполнять команды удаленно, к примеру выполнить cat лога и через пайп сделать его grep уже на своей машине. 

Есть команда, которая копирует файлы через ssh:

scp 

Также ssh можно использовать в качестве прокси, правда, эту возможность нужно включить в конфиге сервера ssh. Если вам неохота поднимать openVPN, но есть доступ к ssh, можно воспользоваться командой

ssh -D 8080

и, настроив браузер, ходить через удаленную машину в интернет.

Если на удаленной машине надо запустить графическую программу, потребуется опция:

ssh -X

она прокидывает x11 и можно запустить даже какой-нибудь Firefox. Браузер будет открыт на удаленной машине, но через x11 окно откроется на локальной машине. Учтите, что комфортно работать в этом можно, только если пинг до удаленной машины небольшой.

Следующая команда позволяет пробрасывать порты в любую сторону.

ssh -L 

Предположим, на удаленном сервере есть mysql. Можно подключиться к нему так, что он как будто окажется поднят локально на порту 12345.

Ну и более расширенная версия. Если у вас есть ssh-сервер с доступом к какому-то другому серверу, используя ssh и внутренний IP второго сервера, можно настроить себе порт 12345 локально так, будто он проброшен на второй сервер.

Если в сети очень много серверов и ресурсов, можно воспользоваться утилитой sshuttle. Она принимает на вход адрес подсети, которая должна проксироваться через ssh, и при подключении к удаленному ресурсу автоматически  переконфигурирует ssh. В итоге все будет получаться очень прозрачно, как будто локально.

Порты можно прокидывать и в другую сторону. Этот способ можно назвать “dyndns для бедных”. Это необходимо, когда вы хотите локальный порт своей машины пробросить куда-то вовне (чтобы кто-то имел к нему доступ).

В данном примере на локальной машине есть веб-сайт, который работает на 80 порту, и этот порт прокидывается на удаленный сервер по ssh. В итоге каждый может подключиться к локальному веб-сайту. 

Наружу можно прокинуть ssh с локальной машины (если она за NAT), чтобы подключаться к ней через какой-то другой ssh сервер. Можно даже прокинуть порт соседней машины (если и сервер, и клиент ssh имеют доступ к этому порту) и многое другое.

Для конфигурирования ssh можно создать файл (в Linux это ~/.ssh/config в домашней директории), где для подключения указать сразу имя пользователя, порты, ключи, интервал переподключения и т.п. 

Пример файла:

Host my-server
     Hostname 1.2.3.4
     User user
     IdentityFile ~/.ssh/my_sever_rsa
     LocalForward 5432 localhost:5432
     LocalForward 8000 localhost:8000
     ServerAliveInterval 300
     ServerAliveCountMax 2

Тогда подключиться к данному серверу можно с помощью команды ssh my-server.

На этом все. А какими командами Linux чаще всего пользуетесь вы?

Спасибо за подготовку подборки Игорю Иванову, Антону Дмитриевскому, Денису Палагута, Александру Метелкину и Николаю Еремину (Максилект).

P.S. Мы публикуем наши статьи на нескольких площадках Рунета. Подписывайтесь на нашу страницу в VK или на Telegram-канал, чтобы узнавать обо всех публикациях и других новостях компании Maxilect.

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