Як (і навіщо) використовувати stderr як для читання, так і для письма?


12

Відповідно до цієї відповіді шилі , lessчитає навігаційні команди з stderr, якщо вона не вдається відкрити /dev/tty.

Це здається дивним, оскільки я ніколи не бачив, щоб щось писало до поточного потоку іншої програми, і я не знаю, як би я це навіть досягнув.

Яка мета stderr бути відкритим як для читання, так і для письма? І якщо це корисно, як я можу це використовувати в сучасних системах? (Чи є якийсь таємний синтаксис, щоб щось вставити в stderr замість stdin, наприклад?)

Відповіді:


7

Я спочатку здивувався. Однак після прочитання відповідей і проведення невеликого розслідування здається простим. Тож ось що я знайшов. (врешті-решт сюрпризу не було.)

Перед перенаправленням stdin, stdout та stderr, як очікується, підключені до одного пристрою.

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

Тому після більшості повторних вказівок (тобто, якщо stderr) не буде переспрямовано. stderr як і раніше підключений до терміналу. Тому його можна прочитати, щоб ввести клавіатуру.

Єдине, що зупиняє файли, які використовуються в несподіваному напрямку, - це умовність, а труби - однонаправлені.

Ще один приклад: спробуйте:

cat | less

Це піде не так після сторінки, коли lessнамагається прочитати термінал (це не сюрприз, як catі читання терміналу).

/dev/ttyє більш загадковою, вона не є посиланням на /proc/self.

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

Подивіться, які відносини між моїм поточним керуючим терміналом та `/ dev / tty`? для пояснення. Дякуємо @StephenKitt за посилання.


Стосовно цього/dev/tty див. Це питання .
Стівен Кітт

6

Коли ви входите, stdin, stdout та stderr підключаються до терміналу, звідки ви входите в систему. Для точніше, tty типово відкривається, а stdout і stderr є результатом двох dup(2)операцій на першому дескрипторі файлу. Це дозволяє читати з stderr, щоб отримати вхід з терміналу.

Як було сказано в іншій відповіді, програми читають з stderr, щоб отримати інтерактивну відповідь на запитання.

Оскільки користувач не може знати, за яких обставин програма читає з stderr, це марна спроба навмисно записати дані в stderr з іншої програми.

Зауважте, що сьогодні зазвичай програми спочатку намагаються відкрити /dev/ttyта використовувати stderr лише у випадку, коли це не працює.

Програми, які читаються лише з stderr, зазвичай ніколи не змінювались до 1979 року, і такі програми зазвичай містять такі конструкції:

int i 1;

або

i =* 2;

які не приймаються сучасними компіляторами C. Як результат, найімовірніше, що сьогодні ви знайдете програму, яка ніколи не відкриється, /dev/ttyа читає інтерактивні відповіді від stderr.


Тож якщо я правильно розумію, оболонка підключається stderrдо tty, коли stdinперенаправляється (через трубу чи інші засоби)? Або просто завжди підключається stderrдо tty?
Драконіс

1
Коли ви входите, stderr підключається до вашого терміналу входу.
шилі

2
i =+ 1ідеально діє C і дорівнює i = (+1). Зрозуміло, колишній є приємним кандидатом на конкурс C.
Г. Сліпен

1
Гаразд, можливо, це просто створює попередження. Я змінив код на щось інше з C у 1977 р.
schily

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.