В заметке (http://xgu.ru/wiki/stdin) подробно рассматривается, что такое стандартные потоки ввода и вывода, и какие вещи с ними можно делать. Рассматриваются как базовые вопросы использования потоков ввода/вывода, так и тонкости и хитрости, например, почему не работает echo text | read val и ряд других.URL: http://xgu.ru/wiki/stdin
Новость: https://www.opennet.ru/opennews/art.shtml?num=22596
То, что доктор прописал, хорошая статья
Исчо лучше!http://gazette.linux.ru.net/rus/articles/abs-guide/index.html
http://gazette.linux.ru.net/rus/articles/abs-guide/c11849.html
http://tldp.org/LDP/abs/html/
http://tldp.org/LDP/abs/html/io-redirection.html
я лучше POSIX[1] почитаю. В этой статье даже не упоминается простой способ избавиться от нежелательного вывода/ввода путем *закрытия* дескриптора. Напр,
$ ls >&- 2>&-А также, что `команда >&файл' и `команда1 |& команда2' являются расширением в tcsh, bash, zsh и отсутствует в ash (almquist shell) и posix shell'е.
[1] http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_...
>я лучше POSIX[1] почитаю. В этой статье даже не упоминается простой способ
>избавиться от нежелательного вывода/ввода путем *закрытия* дескриптора. Напр,
> $ ls >&- 2>&-
>
>А также, что `команда >&файл' и `команда1 |& команда2' являются расширением в tcsh, bash, zsh и отсутствует в ash (almquist shell) и posix shell'е.
>
>[1] http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_...
>&- нормальная вещь, спасибо,но как по мне, неправильно использовать >&- там, где логичнее использовать > /dev/null
Сравните
ls >&-
и
ls > /dev/null
Это уже дело вкуса. С одной стороны, зачем писать, если можно не писать? Это аргумент за >&-. Ведь devfs может быть вообще не смонтирован (в chroot/jail например). Кроме того, так короче.
С другой стороны, /dev/null нагляднее и проще понять где /dev/null заменить на не /dev/null.
Я в общем всецело за /dev/null.
>Это уже дело вкуса. С одной стороны, зачем писать, если можно не писать? Это аргумент за >&-. Ведь devfs может быть вообще не смонтирован (в chroot/jail например). Кроме того, так короче.
>С другой стороны, /dev/null нагляднее и проще понять где /dev/null заменить на
>не /dev/null.
>Я в общем всецело за /dev/null.Дело не в том даже, а в том, что когда вы используете >&-,
то в общем случае добавляется ещё одна ошибка в поток:$ ls >&-
ls: write error: Bad file descriptor
Нет.% ls >&-
%
>Нет.
>
>% ls >&-
>%А скажите, пожалуйста, какая ось у вас?
У меня на GNU/Linux:
% ls >&-
ls: write error: Bad file descriptor
book% bash
$ ls >&-
ls: write error: Bad file descriptor
> $ ls >&-
> ls: write error: Bad file descriptorна FreeBSD все пучком - нет ошибки.
$ ls >&-
$
Linux'у такое поведение с ошибкой можно было б простить, если бы сия функция не была одной из базовых в posix shell'е.
>Linux'у такое поведение с ошибкой можно было б простить, если бы сия
>функция не была одной из базовых в posix shell'е.кроме того это проблема не bash'а, а GNU ls.
>>Linux'у такое поведение с ошибкой можно было б простить, если бы сия
>>функция не была одной из базовых в posix shell'е.
>
>кроме того это проблема не bash'а, а GNU ls.А почему это проблема ls? Разве не у каждой программы ДОЛЖНЫ быть открыты дескрипторы 0, 1 и 2 при её запуске?
Ну не проблема, а скорее особенность.По крайней мере это именно из-за ls (ну и других прог, потому что не только ls так себя ведёт, а многое гнутое из того, что я проверил).
Проблема ли это или не проблема, сложно сказать.
По крайней мере, он бы мог тупо забивать
и пользователю оставалось бы только догадываться,
закрыт дескриптор или нет.Вот как здесь:
#include<stdio.h>main()
{
printf("opennet rulez\n");
fprintf(stderr, "opennet rulez (stderr)\n");
}$ gcc -o /tmp/h h.c
$ /tmp/h
opennet rulez
opennet rulez (stderr)
$ /tmp/h >&-
opennet rulez (stderr)
$Но он заботится о пользователе
и ставит его в курс дела.
Ну, это же хорошо! Лишняя проверка не повредит, а вот её отсутсвие — потенциальный баг в программе.
>Ну, это же хорошо! Лишняя проверка не повредит, а вот её отсутсвие
>— потенциальный баг в программе.Мне вот интересно,
ls и проч. вылетает,
когда видит, что STDOUT закрыт,
или продолжает работать,
просто ошибку выводит?Наверное, вылетает
>Мне вот интересно,
>ls и проч. вылетает,
>когда видит, что STDOUT закрыт,
>или продолжает работать,
>просто ошибку выводит?
>
>Наверное, вылетаетВо-первых, что значит «вылетает»? Завершается раньше времени (но по собственному желанию) или убивается системой (то есть получает сигнал, от которого умирает)?
Да и если ls не убивается, то что ему дальше делать-то? В любом случае завершится.
У меня (GNU) ls >&- возвращает 2, значит, завершается самостоятельно. И, потом, было бы странно сначала проверить stdout на возможность вывода, сообщить о том, что он закрыт, а дальше, несмотря на это, что-то сделать так, чтобы тебя убили.
FreeBSD
>Сравните$ /bin/echo 'Ага.' >&- && echo "Таки-ага." || echo 'Не-а!'
/bin/echo: ошибка записи: Bad file descriptor
Не-а!
$ /bin/echo 'Ага.' > /dev/null && echo "Таки-ага." || echo 'Не-а!'
Таки-ага.
$ _
И эти люди запрещают мне^W^Wрассказывают о кроссплатформенности, переносимоти, позиксвейности и не-баш-измости... http:/openforum/vsluhforumID3/47017.html#7И ведь каждый раз одно, блин, и то же: "-Вы в шеле? -Нет, мы в шеле! -А, я думал, вы в шеле..."
>И эти люди запрещают мне^W^Wрассказывают о кроссплатформенности, переносимоти, позиксвейности и не-баш-измости... http:/openforum/vsluhforumID3/47017.html#7
>
>
>И ведь каждый раз одно, блин, и то же: "-Вы в шеле?
>-Нет, мы в шеле! -А, я думал, вы в шеле..."_ОНИ_ это кто?
Я, наверное, пропустил какую-то жестокую тему
Сначала подумал, что элементарщина, но узнал для себя что-то новое. Спасибо.
> почему не работает echo text | read val и ряд другихОдин написал бред, другой подхватил. Указанная конструкция замечателно работает:
% echo text | read var; echo $var
textвероятно имелось в виду (echo text | read var); echo $var
В общем статья хорошая, но тема скобок совершенно не раскрыта.
>> почему не работает echo text | read val и ряд других
>
>Один написал бред, другой подхватил. Указанная конструкция замечателно работает:
>
>% echo text | read var; echo $var
>text
>У вас какой shell?
tcsh?
В sh/bash это не работает, проверьте, если не лень
>вероятно имелось в виду (echo text | read var); echo $var
>
>В общем статья хорошая, но тема скобок совершенно не раскрыта.Тема скобок это да
>[оверквотинг удален]
>>Один написал бред, другой подхватил. Указанная конструкция замечателно работает:
>>
>>% echo text | read var; echo $var
>>text
>>
>
>У вас какой shell?
>
>tcsh?
>Хотя однако, какой tcsh, там же read нет.
Так что таки bash у вас.Покажите как работает, пожалуйста
>Хотя однако, какой tcsh, там же read нет.
>Так что таки bash у вас.У меня zsh.
В zsh работает, проверил только что.
Спасибо за поправку
> Хотя однако, какой tcsh, там же read нет.в tcsh есть $< для чтения значения переменной из стандартного ввода
> set foo=$<
blah
> echo Here is my answer: $fooHere is my answer: blah
>> Хотя однако, какой tcsh, там же read нет.
>
>в tcsh есть $< для чтения значения переменной из стандартного ввода
>
> > set foo=$<
>
> blah
> > echo Here is my answer: $foo
>
> Here is my answer: blahЭто немножечко не то.
Нужно же было прочитать строку из вывода другого процесса.%> echo value | set foo=$<
%> echo $foo%>
Не выводит.
Как сделать чтобы работало?
Вариант с командной подстановкой не предлагать,
нужно чтобы читалась одна строка.
foo=$(echo value|head -n 1)
> foo=$(echo value|head -n 1)в случае tcsh скорее
> set foo=`echo value`
Не, ребята, это всё не то.
нужно чтобы read читал только одну строку,
а остальное не трогал.Например, как вы с помощью командной подстановки,
которую вы рекомендуете,
сделаете такое:|while read line
do
....
doneКак это сделать в tcsh с помощью той конструкции, которую
вы выше рекомендовали?
>> почему не работает echo text | read val и ряд других
>
>Один написал бред, другой подхватил. Указанная конструкция замечателно работает:Note that unlike some other shells, sh executes each process in the pipe‐
line as a child of the sh process. Shell built‐in commands are the
exception to this rule. They are executed in the current shell, although
they do not affect its environment when used in pipelines.т.е. команды в конвеере (каналы) не влияют на окружение, в коем они запущены. Кстати, как правильно имплементировать конвееры не оговорено в POSIX. Так что zsh себя тоже правильно ведет.
Спасибо, очень полезно. Большинство знал, но некоторые моменты облегчат работу в дальнейшем.
Merci, очень полезная статья.