Тестируется через stdin stdout

Тестируется через stdin stdout

Что касается файловой системы языка С, то в начале выполнения программы автоматически открываются три потока. Это stdin (стандартный поток ввода), stdout (стандартный поток вывода) и stderr (стандартный поток ошибок). Обычно эти потоки направляются к консоли, но в средах, которые поддерживают перенаправление ввода/вывода, они могут быть перенаправлены операционной системой на другое устройство. (Перенаправление ввода/вывода поддерживается, например, такими операционными системами, как Windows, DOS, UNIX и OS/2.)

Так как стандартные потоки являются указателями файлов, то они могут использоваться системой ввода/вывода языка С также для выполнения операций ввода/вывода на консоль. Например, putchar() может быть определена таким образом:

Вообще говоря, stdin используется для считывания с консоли, a stdout и stderr — для записи на консоль.

В роли указателей файлов потоки stdin , stdout и stderr можно применять в любой функции, где используется переменная типа FILE * . Например, для ввода строки с консоли можно написать примерно такой вызов fgets() :

И действительно, такое применение fgets() может оказаться достаточно полезным. Как уже говорилось в этой книге, при использовании gets() не исключена возможность, что массив, который используется для приема вводимых пользователем символов, будет переполнен. Это возможно потому, что gets() не проводит проверку на отсутствие нарушения границ. Полезной альтернативой gets() является функция fgets() с аргументом stdin , так как эта функция может ограничивать число читаемых символов и таким образом не допустить переполнения массива. Единственная проблема, связанная с fgets() , состоит в том, что она не удаляет символ новой строки (в то время как gets() удаляет!), поэтому его приходится удалять "вручную", как показано в следующей программе:

He забывайте, что stdin , stdout и stderr — это не переменные в обычном смысле, и им нельзя присваивать значение с помощью fopen() . Кроме того, именно потому, что в начале работы программы эти указатели файлов создаются автоматически, в конце работы они и закрываются автоматически. Так что и не пытайтесь самостоятельно их закрыть.

Связь с консольным вводом / выводом

В языке С консольный и файловый ввод/вывод не слишком отличаются друг от друга. Функции консольного ввода/вывода, описанные в главе 8, на самом деле направляют результаты своих операций на один из потоков — stdin или stdout , и по сути, каждая из них является специальной версией соответствующей файловой функции. Функции консольного ввода/вывода для того и существуют, чтобы было удобно именно программисту.

Как говорилось в предыдущем разделе, ввод/вывод на консоль можно выполнять с помощью любой файловой функции языка С. Однако для вас может быть сюрпризом, что, оказывается, операции ввода/вывода на дисковых файлах можно выполнять с помощью функции консольного ввода/вывода, например, printf() ! Дело в том, что все функции консольного ввода/вывода, о которых говорилось в главе 8, выполняют свои операции с потоками stdin и stdout . В средах, поддерживающих перенаправление ввода/вывода, это равносильно тому, что stdin или stdout могут быть перенаправлены на устройство, отличное от клавиатуры или экрана. Проанализируйте, например, следующую программу:

Предположим, что эта программа называется TEST. При ее нормальном выполнении на экран выводится подсказка, затем читается строка, введенная с клавиатуры, и, наконец, эта строка выводится на экран. Однако в средах, в которых поддерживается перенаправление ввода/вывода, один из потоков stdin или stdout (или оба одновременно) можно перенаправить в файл. Например, в среде DOS или Windows следующий запуск TEST

приводит к тому, что вывод этой программы будет записан в файл по имени OUTPUT. А следующий запуск TEST

направляет поток stdin в файл по имени INPUT, а поток стандартного вывода — в файл по имени OUTPUT.

Когда С-программа завершается, то все перенаправленные потоки возвращаются в состояния, которые были установлены по умолчанию.

Перенаправление стандартных потоков: функция freopen()

Для перенаправления стандартных потоков можно воспользоваться функцией freopen() . Эта функция связывает имеющийся поток с новым файлом. Так что она вполне может связать с новым файлом и стандартный поток. Вот прототип этой функции:

где имя_файла — это указатель на имя файла, который требуется связать с потоком, на который указывает указатель поток . Файл открывается в режиме режим ; этот параметр может принимать те же значения, что и соответствующий параметр функции fopen() . Если функция freopen() выполнилась успешно, то она возвращает поток , а если встретились ошибки, — то NULL .

В следующей программе показано использование функции freopen() для перенаправления стандартного потока вывода stdout в файл с именем OUTPUT.

Читайте также:  Как присвоить ip адрес камере

Статья посвящена работой с потоками данных в bash. Я постарался написать ее наиболее доступным и простым языком, чтобы было понятно даже новичкам в Linux.

В одной из моих статей мы рассматривали запись звука в файл с помощью команды:

Эта команда читает файл (устройство) /dev/audio с помощью команды cat и перенаправляет информацию из него в файл /tmp/my.sound (с помощью оператора >).

У каждой программы существует 3 системных потока: stdout, stderr, stdin.

stdout

Стандартный поток вывода данных для программ. Например, когда мы пишем команду ls, то список папок и файлов она выводит именно в этот поток, который отображается у нас в консоли:

stderr

Поток вывода ошибок. Если программа не смогла сделать все как надо — она пишет именно в этот поток. Например, когда rm пытается удалить несуществующий файл:

$ rm example.txt
rm: example.txt: No such file or directory

stdin

Поток ввода данных. А вот это довольно интересный и удобный поток. Например, его использует вэб-сервер, когда просит интерпретаторы выполнить скрипты через CGI. Мы тоже можем попробовать:

В этом примере мы встретили оператор перенаправления потока вывода. Мы остановимся на нем позже.

Для начала рассмотрим перенаправление потоков в файлы, устройства и другие потоки.

В этом примере мы направили stdout команды ls в файл 1.txt. Читаем его:

Да, все успешно записалось.

Теперь попробуем направить stderr команды rm:

Здесь мы использовали номер потока stderr (2). По умолчанию оператор > перенаправляет поток stdout, который имеет номер 1. Чтобы направить другой поток, надо перед оператором > поставить его номер.

Мы можем направлять одни потоки в направлении других:

В этом примере мы направили поток stdout в файл 1.txt, а затем направили stderr туда же, куда направлен stdout с помощью оператора & перед номером потока.

Теперь давайте поиграем с потоком stdin. Например, я хочу найти все папки ".svn" в некотором проекте и удалить:

Команда find с параметром. выводит в stdout все вложенные папки и файлы, которые находит в данной папке и во всех вложенных.

Теперь нам надо выбрать только папки с именем ".svn":

Оператор | перенаправляет stdout одного приложения в stdin следующего. То есть все строки найденные с помощью find пошли в команду grep, которая выбирает строки по определенным условиям и выводит их. Здесь условие — это регулярное выражение, которое говорит о том, что строка должна заканчиваться на "/.svn".

Нужные папки мы выбрали, осталось их удалить.

И снова новый оператор: `. Он забирает stdout из команды, которую он окружает и вставляет в данное место как строку.

Получается, что мы запросили все файлы, выбрали из них папки с именем ".svn" и отдали результат как аргументы команде rm. В этом случае у нас будут проблемы если имена файлов и папок содержат пробелы. Исправляем ситуацию:

Теперь мы отдаем нужные файлы команде xargs, которая вызывает rm -Rf и в качестве параметров использует свой stdin построчно. Задача решена.

Каждый может помочь развитию данной серии статей, поделиться своим опытом. Добро пожаловать: http://www.linuxman.ru. Все изменения в Вики я буду со временем переносить и в Хабр.

Ой, у вас баннер убежал!

Редакторский дайджест

Присылаем лучшие статьи раз в месяц

Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.

  • Скопировать ссылку
  • Facebook
  • Twitter
  • ВКонтакте
  • Telegram
  • Pocket

Похожие публикации

  • 10 мая 2017 в 16:18

Bash-скрипты, часть 10: практические примеры

Bash-скрипты, часть 9: регулярные выражения

Bash-скрипты, часть 8: язык обработки данных awk

Заказы

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 43

А по-моему, вполне понятно все написано в книжках. Разобраться совсем недолго… Примеры книг могу привести, если надо.

А так за статью(не считаем ошибки) респект. Немногие сейчас отваживаются их писать)

Команда find с параметром * выводит в stdout все вложенные папки и файлы, которые находит в данной папке и во всех вложенных.

Неверно. Это сделает команда find .

Не забываем, что globbing (замена wildcards) происходит в шелле. И * по умолчанию не расширяется на dot entries в текущем каталоге.

Нельзя не вспомнить про будильник настоящего юниксоида:

Настоящий юниксоид напишет так:

Читайте также:  Money megafon ru перевод

sleep 8h && cat /dev/urandom > /dev/dsp

Будет (собственно я не говорил, что Ваш код в корне не верен), но настоящий юниксоид напишет:
sleep 8h && cat /dev/urandom > /dev/dsp

Так как код:
sleep 8h; cat /dev/urandom > /dev/dsp
при отсутствии /bin/sleep сразу начнет звенеть…

Ваш пример довольно безобидный, но когда начинают писать
cd /dir1/dir2/dir3; rm *
становится страшно…

Спасибо за совет, но, прочитав мануал, я понял эту команду как:

tee [-ai] [file . ]
The tee utility copies standard input to standard output, making a copy
in zero or more files. The output is unbuffered.

cat ./file.txt | grep ‘key’ | tee ./file2.txt | grep ‘subkey’ > ./file3.txt

Как ./file2.txt направить не в физический файл, а в пайп, где я еще хочу сделать sort?

У тебя есть такой пример:

Извини, у меня нет цензурных слов. За такое я отрываю разработчикам руки. Такой код в скриптах — это бомба замедленного действия, она срабатывает редко, но неожиданно и разрушительно. О grep-е после find-а и xargs rm вместо -delete уже говорили, но это можно попытаться оправдать тем, что примеры учебные и искуственные. А вот опасность этого примера оправдать нельзя!

Автор, создай у себя, для эксперимента директорию где-нибудь в темпе:

В «документы» положи очень важные и ценные тебе документы. В «документы на удаление» — ерунду. А теперь выполни эту команду и сожалей, что директория «документы» исчезла. Не .svn в этой директории, а «документы» целиком!

Писать так — опасно, учить других писать так — во сто крат опасней! Читать маны перед написанием учебной статьи — напротив, не только неопасно, но и крайне полезно.

Угу, этот пример тоже хорош:

Такой же убийственный

Спасибо за дельный комментарий.
Но если все таки забыть про учебную составляющую и обратить внимание на саму задачу удаления каталогов .svn, то у меня возник вот какой вопрос: как же правильно написать команду?

У меня не получилось удалить каталоги .svn с использованием -delete, так как я создал там вложенные файлы (это часто бывает в реальной жизни в таком каталоге).

find. -type d -and -iname ‘.svn’ -delete
find: cannot delete `./документы/.svn’: Каталог не пуст

В конце концов появился вот такой вариант:

find. -type d -and -iname ‘.svn’ -execdir rm -Rf .svn ; 2>/dev/null

Есть ли более оптимальный?

Обычно пользуюсь find -print0 | xargs -0 . А только средствами find… попробуйте

find . -depth ( -path ‘*/.svn/*’ -or -iname ‘.svn’ ) -delete

Хотя поздновато уже, не ручаюсь.

find ищет по каким-то условиям и выполняет определённое действие с результатом поиска. Дело в том, что по умолчанию find делает -print, то есть выводит результат на стандартный вывод, разделяя имена переводом строки.
xargs читает со стандартного ввода записи, разделяя, их, среди прочего, и пробелами. Таким образом, если find найдёт файл с именем «раз два», то xargs запустит указанную команду с аргументами «раз» и «два». Нам нужно, чтобы find разделял записи разделителем, который не может присутствовать в именах файлов. Среди ext2/3 таких символов два — это нулевой символ (не имеет печатаемого обозначения) и символ прямого слэша. Прямой слэш, кажется, в некоторых файловых системах может являться частью имени файла, потому нам остаётся только нулевой символ.
Как сказано в мануале в первых строках по find: «you should probably consider using ‘-print0’ instead».
Действие -print0 заставляет find вывести на стандартный вывод результаты, разделяемые нулевым символом, а опция -0 у xargs заставляет в качестве разделителя записей принимать только нулевой символ.

В моём мане (это не сарказм, маны на разных системах бывают очень разные) есть такой пример для этого дела:

Что касается возможности запуска без xargs — для скриптов я бы посоветовал такую конструкцию:

Для применения вручную, после запуска без -delete и изучения списка:

При этом, файлы и директории типа .svnlalala тоже будут уничтожены, если присутствуют.

Есть ли способ поймать stdout и stderr в Visual Studio? Например, когда я использую cout

Я унаследовал некоторый код, который периодически (случайно) терпит неудачу из-за ошибки ввода/вывода, возникающей во время вызова для печати. Я пытаюсь…

В Python, например, я могу сделать следующее: realout = sys.stdout sys.stdout = StringIO.StringIO() some_function() # prints to stdout get captured…

У меня есть два процесса, написанные на C++, передаваемые один за другим. Один дает какую-то информацию другому stdin, затем они…

Читайте также:  Бесплатный фоторедактор для инстаграм

Я пытаюсь написать консольное приложение Delphi, которое создает TStream для его стандартного ввода и другой TStream для его стандартного вывода….

Включена ли по умолчанию буферизация вывода в интерпретаторе Python для sys.stdout? Если ответ положительный, каковы все способы его отключения? Предложения…

Когда я нажимаю на одну из ссылок в меню, она переходит к url-адресу страницы, например: http://www.url.com/my-page.aspx но только после того,…

Я пытаюсь изучить Эрланг через interviewstreet . Я просто изучаю язык сейчас, так что я почти ничего не знаю. Мне…

У меня есть скрипт, который я хочу запустить из python (2.6.5), который следует логике ниже: Запрос пароля. Выглядит как («введите…

После обновления до Snow Lion я начал получать эти ошибки в Flash Builder / Eclipse при попытке использовать SVN: Failed…

Я пишу программу C под Android / Linux, которая выполняет системную команду. Команда выводит некоторый текст в stdout, и я…

У меня есть приложение java, которое использует log4j. Конфиг: log4j.rootLogger=info, file log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=$/logs/app.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d [%t] %c %p %m%n Таким…

При написании большого куска STDOUTв PHP вы можете сделать это: echo

Я боролся с этой проблемой при написании сценария bash. В основном, я хочу измерить время работы программы на удаленном сервере,…

Я пытаюсь получить datetimepicker, чтобы вернуть дату в следующем формате: 08-SEP-2012. Возвращаемый формат будет частью веб-адреса и поэтому очень специфичен….

Когда я запускаю тесты./manage.py test, все, что я отправляю в стандартный вывод, printне отображается. Когда тесты терпят неудачу, я вижу…

#include #include #define MAXN 15 char forbid[MAXN][MAXN]; int dp[2][1

Я пытаюсь выяснить, как подавить отображение пользовательского ввода на stdout. raw_input() после любой инструкции print сохраняется то, что ввел пользователь….

Мне было интересно, разница между stdoutи STDOUT_FILENOв Linux C. После некоторых поисковых работ я делаю следующий вывод. Не могли бы…

Я пытаюсь напечатать вывод / ошибку для консоли и файла журнала с помощью кода ниже. fun1()< эхо » внутри fun1″…

Я знаю, что ffmpeg может считывать данныеstdin, а не читать с диска с помощью ffmpeg -i -. Поддерживается ли это…

Требование это … У нас 3 веб-приложения развернуты на сервере RHEL-5, мы развернули приложения с tomcat 6.0.16. Мы хотим настроить…

Есть ли какая-то особая причина для результатов java -version?stderr Например, эта команда выполняется из строки приглашения Windows: java -version >…

У меня есть сценарий Perl, который раздваивается и демонизируется. Он управляется cron, поэтому, чтобы не оставлять зомби вокруг, я выключил…

Я использую Aptana studio 3.2.2 для разработки и отладки графического интерфейса python, который использует wxPython и matplotlib. Когда я останавливаю…

В начале моей программы python у меня есть следующая строка: sys.stdout = open(‘stdout_file’, ‘w’) В середине моей программы я хотел…

Я относительно новичок в python и, очевидно, новичок в stackoverflow. Моя цель состоит в том, чтобы создать файл, содержащий информацию…

Я прочитал этот вопрос stackoverflow, и я успешно перенаправляю stdout. Но то, как работает упомянутый код, я полностью теряю свой…

Предположим на мгновение, что нельзя использовать print(и, таким образом, пользоваться преимуществами автоматического обнаружения кодирования). Так что остается с нами sys.stdout….

У меня есть программа, которая отображает выходные данные журнала в stdout. Таким образом, если я открою сеанс telnet для моего…

Каждый раз, когда я выполняю команду, я хочу, чтобы stderr перенаправлялся в /tmp / test . Тестовый файл должен содержать…

Я не могу получить вывод файла, чтобы работать правильно: record = File.open(«/tmp/record», «w») old_stdout = $stdout $stdout = record $stderr…

Я пытаюсь прочитать выходные данные исполняемого файла (a), который написан на C++ из моего скрипта python. Я работаю в Linux….

У меня есть текстовый файл с разделителями»|». Мне нужно объединить 2 поля, а затем вставить это в xml-файл, заданный другим…

У меня есть консольное приложение c++, которое печатает некоторые выходные данные постоянно, в то время как оно также принимает команды…

При попытке использовать команду find / для поиска vi файла с помощью перенаправления я получаю каждый файл, указанный на сервере…

У меня есть логгер RotatingFileHandler. Я хочу перенаправить всех Stdoutи Stderrк логгеру. Как это сделать?

Ссылка на основную публикацию
Тест для определения цвета волос
Пожалуйста, не копируйте понравившиеся вам статьи незаконно. Мы предлагаем вам разместить активную ссылку на наш сайт в случае, если вы...
Стим показывает что я не в сети
Не редко пользователи Steam встречаются с проблемой, когда подключение к интернету есть, браузеры работают, но клиент Стим не грузит страницы...
Стим саппорт украли аккаунт
Если ваш аккаунт Steam украли или взломали, то до его восстановления вам необходимо выполнить действия, указанные ниже, иначе аккаунт может...
Тест графики видеокарты 3dmark
Наиболее известная программа тестирования производительности, ставшая де-факто стандартом и точкой отсчета в измерениях игровых возможностей видеокарт. Основную популярность программе обеспечило...
Adblock detector