Помогите разобраться с Redirections в Bash
Не совсем разобрался в логике перенаправления. Допустим у меня есть в корневой директории /root такие файлы
ls -l
total 16692
-rw-r--r-- 1 root root 1249479 May 5 22:40 bootstrap-5.0.0-examples.zip
-rw-r--r-- 1 root root 786 May 9 12:49 in
drwxr-xr-x 9 root root 4096 May 5 16:43 nginx-1.19.0
-rw-r--r-- 1 root root 1043748 May 26 2020 nginx-1.19.0.tar.gz
drwxrwxr-x 18 root root 4096 May 5 16:52 openssl-1.1.1g
-rw-r--r-- 1 root root 9801502 Apr 21 2020 openssl-1.1.1g.tar.gz
-rw-r--r-- 1 root root 177 May 9 12:00 out_bash
drwxr-xr-x 9 1169 1169 12288 May 5 16:10 pcre-8.44
-rw-r--r-- 1 root root 2090750 Feb 12 2020 pcre-8.44.tar.gz
-rw-r--r-- 1 root root 2253029 May 7 11:02 v4.0.0.zip
drwxr-xr-x 14 501 staff 4096 May 5 16:18 zlib-1.2.11
-rw-r--r-- 1 root root 607698 Jan 15 2017 zlib-1.2.11.tar.gz
Если я выполню
bash > out.txt
То теперь, если в тойже директории выполнить ls, то ls отобразит пустую директорию!
И чтобы я снова мог видеть свои файлы и деректории мне надо выполнить exit. При этом в файле out.txt будет содержать список всех моих файлов и каталогов.
Если это возможно, как это можно применить практически?
Ответы (1 шт):
ls отобразит пустую директорию!
нет, вывод программы, который она отправит в свой stdout, попадёт не к вам на терминал, а будет записано в файл out.txt.
попробую наглядно продемонстрировать.
вот так выглядят стандартные файловые дескрипторы текущего процесса bash (назовём его «процесс номер один») до начала экспериментов:
$ ls -ld /proc/$$/fd/{0,1,2}
lrwx------ 1 user user 64 May 10 17:28 /proc/11480/fd/0 -> /dev/pts/7
lrwx------ 1 user user 64 May 10 17:28 /proc/11480/fd/1 -> /dev/pts/7
lrwx------ 1 user user 64 May 10 17:28 /proc/11480/fd/2 -> /dev/pts/7
все три (0 — stdin, 1 — stdout, 2 — stderr) — символические ссылки на /dev/pts/7 — устройство псевдо-терминала, созданное (используемым мной) эмулятором терминала.
всё, что текущий процесс bash (и его потомки) выведет в stdout и stderr, попадёт в устройство псевдо-терминала, а эмулятор терминала отобразит нам в рисуемом им окне.
выполняя команду bash > out.txt, мы запускаем новый процесс bash (назовём его «процесс номер два»), причём его stdout сразу же будет «привязан» к файлу out.txt: всё, что этот процесс (и любые порождённые им дочерние процессы) отправит в stdout, будет записываться в этот файл.
смотрим, что произошло с файловыми дескрипторами у нового процесса:
$ ls -ld /proc/$$/fd/{0,1,2}
хм. ничего не видно. ах, да! мы же перенаправили stdout в файл out.txt. если заглянуть в этот файл из соседнего терминала, то увидим выведенное процессом ls:
lrwx------ 1 user user 64 May 10 18:01 /proc/22409/fd/0 -> /dev/pts/7
l-wx------ 1 user user 64 May 10 18:01 /proc/22409/fd/1 -> /home/user/out.txt
lrwx------ 1 user user 64 May 10 18:01 /proc/22409/fd/2 -> /dev/pts/7
обратите внимание: стандартный дескриптор номер 1 (stdout) для выполняемого процесса является ссылкой на файл out.txt. именно в этот файл и был записан вывод процесса ls, который он отправил в свой stdout (который унаследовал от своего родителя — «процесса номер два»).
а если сейчас мы выполним команду exit, то завершим работу «процесса номер два», и вернёмся к изначальному состоянию — к «процессу номер один». у которого все три стандартных дескриптора «закреплены» за устройством псевдо-терминалом (обратите внимание на номер процесса — 11480 — он тот же самый, что и в первом листинге):
$ ls -ld /proc/$$/fd/{0,1,2}
lrwx------ 1 user user 64 May 10 18:08 /proc/11480/fd/0 -> /dev/pts/7
lrwx------ 1 user user 64 May 10 18:08 /proc/11480/fd/1 -> /dev/pts/7
lrwx------ 1 user user 64 May 10 18:08 /proc/11480/fd/2 -> /dev/pts/7
Если это возможно, как это можно применить практически?
перенаправление потоков ввода-вывода используется буквально повсеместно. берите любой shell-скрипт — практически наверняка увидите в нём и перенаправления.