LINUX.ORG.RU
ФорумTalks

Как работают обратные апострофы?


0

0

Subject.

Это вообще на уровне шелла или системных вызовов работает? Подозреваю, что шелл делает mkfifo в /tmp и подставляет его имя вместо строки в обратных апострофах - по крайней мере, так бы я реализовал. А как на самом деле?

★★★

всё проще:

если необходимо выполнить "cmd1 `cmd2`" то сначала выполняется cmd2, её output кладётся в некий буфер, который потом передаётся в качестве аргументов для cmd1.

anonymous
()

Пайп действительно создаётся, только неименованый (как для |, системным вызовом pipe(2)). Делает это всё шелл.

slav ★★
()

Если уж на то пошло, то объясните как работает вот такая конструкция?
diff <(some_command) <(another_command)
это диффает аутпут двух комманд сразу, без промежуточных файлов, или промежуточные файлы все-таки создаются башем? Что бы напечатал diff, если бы у него в самом начале стояло что-то вроде printf("argv1=%s, argv2=%s",argv[1],argv[2]) ?

Deleted
()
Ответ на: комментарий от Deleted

здесь вроде бы создается именнованный пайп и его имя подставляется.

Но кстати именно эта конструкция не является стандартной для шелла в силу своей нетривиальности

dilmah ★★★★★
()

[sikon@lucidfox:~/projects]$ ./parg `echo a` `echo b`
argv[0]: ./parg
argv[1]: a
argv[2]: b
[sikon@lucidfox:~/projects]$ ./parg <(echo a) <(echo b)
argv[0]: ./parg
argv[1]: /dev/fd/63
argv[2]: /dev/fd/62

Sikon ★★★
() автор топика
Ответ на: комментарий от Deleted

> diff <(some_command) <(another_command)

Создаются временные файлы с выводом команд, потом они передаются диффу. Файлы лежат в /tmp. Потом удаляются.

Zmacs
()
Ответ на: комментарий от Zmacs

> А ежели сделать readlink на /dev/fd/63 - то он покажет на временный файл

А вот нихрена. Там неименованый канал (пайп) создаётся.

$ ls -l <(echo a)
lr-x------ 1 slava users 64 Апр 29 18:35 /dev/fd/63 -> pipe:[9789073]

Временные файлы в этом случае создаются только если система не умеет неименованых каналов. Это даже в man bash написано.

slav ★★
()

Кстати, у баша есть ещё одна интересная функция: можно перенаправлять файловые дескрипторы (stdin, stdout, и т. д.) в/из сети. Например так:

$ cat </dev/tcp/smtp.yandex.ru/25
220 Yandex ESMTP (NO UCE)(NO UBE) server ready at Sun, 29 Apr 2007 18:39:40 +0400

Пути вида /dev/tcp и /dev/udp обрабатываются башем, не надо пытаться искать соответствующие каталоги в /dev :) Правда, дебиановцы говорят, что у них эта функциональность в баше отключена.

slav ★★
()
Ответ на: комментарий от true

> zsh создает /proc/7693/fd/11 -> pipe:[36824]

Так. Объясняю механизм как это работает. Шелл с помощью системного вызова pipe(2) создаёт канал. Один конец канала (его дескриптор) даёт процессу, указаному в <(...), в качестве стандартного вывода, основному же процессу даёт аргумент вида /dev/fd/N, где N - номер дескриптора второго конца канала. /dev/fd является ссылкой на /proc/self/fd, который содержит информацию о файловых дескрипторах данного процесса, представляемую в виде ссылок (ссылки это на самом деле "не совсем настоящие": если попробовать открыть файл вида pipe:[N] или socket:[N], на который "ссылается" ссылка, то будет открываться файл с таким именем, а не пайп или сокет; насколько я понимаю, операции с ними обрабатываются ядром особым образом (а не как обычные ссылки)). Открытие такого файла процессом эквивалентно дублированию файлового дескриптора. Таким образом, после открытия файла /dev/fd/N, процесс получает второй конец канала, подсоединённого к стандартному выводу другого процесса.

slav ★★
()
Ответ на: комментарий от slav

то что в данном случае был использован /dev/fd/... это детали конкретной реализации. С равным успехом создается просто именованный пайп и используется его имя

dilmah ★★★★★
()
Ответ на: комментарий от slav

> не надо пытаться искать соответствующие каталоги в /dev

Хех... помню, как я, пытаясь настроить в старом Дебиане сеть, искал /dev/eth0... Вот времена были, не то что сейчас - всё из коробки работает :).

Sikon ★★★
() автор топика
Ответ на: комментарий от dilmah

> С равным успехом создается просто именованный пайп и используется его имя

Или временный файл если система не поддерживает каналов вообще.

Кстати, всё это довольно подробно расписано в man bash.

slav ★★
()
Ответ на: комментарий от slav

> $ cat </dev/tcp/smtp.yandex.ru/25 

[sikon@lucidfox:~/1stneed]$ cat /dev/tcp/smtp.yandex.ru/25 
cat: /dev/tcp/smtp.yandex.ru/25: No such file or directory
[sikon@lucidfox:~/1stneed]$ cat </dev/tcp/smtp.yandex.ru/25 
bash: /dev/tcp/smtp.yandex.ru/25: No such file or directory

Sikon ★★★
() автор топика
Ответ на: комментарий от Sikon

"Правда, дебиановцы говорят, что у них эта функциональность в баше отключена."

anonymous
()
Ответ на: комментарий от slav

>$ cat </dev/tcp/smtp.yandex.ru/25 220 Yandex ESMTP (NO UCE)(NO UBE) server ready at Sun, 29 Apr 2007 18:39:40 +0400

и правда, работает =)

WerNA ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.