Pull to refresh

Кручу-верчу, запутать хочу

Level of difficultyEasy
Reading time2 min
Views14K

Салют! В этой небольшой статье я попытался собрать необычные и малоизвестные трюки с перенаправлениями в bash, которые могут значительно упростить работу.

/dev/tcp

Многие пользователи Linux не подозревают, что bash особым образом обрабатывает перенаправление в файл /dev/tcp/host/port, и если host - это допустимое имя хоста или ip адрес, а port - целое число порта или имя службы, пытается открыть соответствующий TCP-сокет.

Например, перенаправим вывод TCP сервера времени на cat и выведем на экран:

$cat < /dev/tcp/time.nist.gov/13
60311 24-01-02 10:43:53 00 0 0 798.9 UTC(NIST) *

Более сложный пример - HTTP запрос. Давайте создадим новый файловый дескриптор, перенаправим на него строку HTTP-запроса, затем прочитаем ответ.

$exec 5<>/dev/tcp/google.de/80
$echo -e "GET / HTTP/1.1\nhost: google.de\n\n" >&5
$cat <&5 | head
HTTP/1.1 301 Moved Permanently
Location: http://www.google.de/
Content-Type: text/html; charset=UTF-8
Date: Thu, 18 Nov 2021 08:27:18 GMT
Expires: Sat, 18 Dec 2021 08:27:18 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 218
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

Placeholder -

Некоторые команды, например tar, воспринимают символ - как перевод на стандартный вывод, что позволит воспользоваться результатом работы команды без создания промежуточных файлов, например создадим бэкап директории /www/data и скопируем по ssh:

tar zcvf - /www/data | ssh user@remoter "cat > /backup/wwwdata.tar.gz"

Группировка команд

Передача стандартного вывода одной команды в стандартный ввод другой команды - мощный инструмент. Но что, если вам нужно передать стандартный вывод нескольких команд? Для того чтобы объединить вывод нескольких команд можно использовать группировку команд, для этого используется синтаксис:{ command1; command2; }, например объединим вывод команд ls, чтобы подсчитать количество файлов в двух директориях:

$mkdir dir{1,2}
$touch dir1/test1.txt
$touch dir2/test2.txt
${ ls dir1; ls dir2; } | wc -l
2

Подмена процессов

Подстановка(подмена) процессов - это мощная и гибкая функция Bash, которая позволяет обрабатывать выходные данные команды как файл, упрощая объединение и манипулирование данными из нескольких команд. Для реализации использует следующий синтаксис: <(команда) — этот синтаксис создает именованный канал (также известный как FIFO) и соединяет с ним выходные данные команды внутри скобок. Именованный канал ведет себя как файл, что позволяет использовать его в качестве входных данных для другой команды. >(команда) – этот синтаксис также создает именованный канал, но подключает его к вводу команды внутри скобок. Это позволяет перенаправить вывод одной команды на ввод другой команды.

Таким образом, можно сравнить вывод двух команд с помощью diff, как если бы мы сохранили его в файлы:

$diff <(ls dir1) <(ls dir2) 
< test1.txt
---
> test2.txt

Или перенаправим вывод ls на вход grep и wc:

ls | tee >(grep 'txt$') >(wc -l) > /dev/null 

Заключение

Надеюсь, приведенные примеры показались вам интересными и полезными, благодарю за ваше время и внимание, эффективных скриптов, элегантных решений вам!

Tags:
Hubs:
Total votes 73: ↑72 and ↓1+71
Comments16

Articles