И снова приглашаем погрузиться в команды GNU/Linux, которые удобно использовать разработчику для решения повседневных задач. Напоминаем, подборка ориентирована на тех, кто не хочет залезать глубоко в систему, но по работе вынужден иногда ходить на Linux-сервер.
В первой части мы обсудили запросы общей информации о пользователях и системе, работу с файлами, процессами и текстом. Сегодня речь пойдет о возможностях bash, работе с сетью и ssh.
Статья написана по мотивам ИТ-посиделки, где мы обменивались полезными лайфхаками.
Команды 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 -f 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 https://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 чаще всего пользуетесь вы?
Спасибо за подготовку подборки Игорю Иванову, Антону Дмитриевскому, Денису Палагута, Александру Метелкину и Николаю Еремину (Максилект).