Помогите разобраться с 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 шт):

Автор решения: aleksandr barakin

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

все три (0stdin, 1stdout, 2stderr) — символические ссылки на /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-скрипт — практически наверняка увидите в нём и перенаправления.

→ Ссылка