Вывод данных и ошибок в командную строку

Как записывать данные в os.Stdout и os.Stderr

1. Создайте файл со следующим содержимым:

Форум Гоферов

Мы работаем над форумом для программистов на Golang. Очень нужны модераторы которые хотят помочь с ответами для новичков и помочь в развитии Go-сообщества.

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

stdouterr.go

Go

package main

import (
«fmt»
«io»
«os»
)

func main() {

// Простая запись строки
io.WriteString(os.Stdout,
«Это строка для стандартного вывода.\n»)

io.WriteString(os.Stderr,
«Это строка для стандартного вывода ошибки.\n»)

// Stdout/err имплементации
// интерфейс записи
buf := []byte{0xAF, 0xFF, 0xFE}
for i := 0; i < 200; i++ {
if _, e := os.Stdout.Write(buf); e != nil {
panic(e)
}
}

// Пакет fmt также можно использовать
fmt.Fprintln(os.Stdout, «\n»)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

packagemain

import(

«fmt»

«io»

«os»

)
 

funcmain(){

// Простая запись строки

io.WriteString(os.Stdout,

«Это строка для стандартного вывода.\n»)

io.WriteString(os.Stderr,

«Это строка для стандартного вывода ошибки.\n»)

// Stdout/err имплементации

// интерфейс записи

buf=byte{0xAF,0xFF,0xFE}

fori=;i<200;i++{

if_,e=os.Stdout.Write(buf);e!=nil{

panic(e)

}

}

// Пакет fmt также можно использовать

fmt.Fprintln(os.Stdout,»\n»)

}

2. Запустите код через ;
3. Посмотрите на результат:

Shell

Это строка для стандартного вывода.
Это строка для стандартного вывода ошибки.
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������

1
2
3

Этострокадлястандартноговывода.

Этострокадлястандартноговыводаошибки.

������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������

Как и , и являются файловыми дескрипторами. Они имплементируют интерфейс . В предыдущем примере показаны несколько способов записи через функцию с использованием API , а также через пакет и функции .

Управление потоками

Для перенаправления каналов в терминале, применяют определенные символы. Рассмотрим каждый из них на примере команды поиска системных файлов, которые содержат слово — core. Все найденные файлы будут формироваться в поток STDOUT. Те найденные файлы, к которым у обычного пользователя нет доступа будут попадать в STDERR.

> — вывод STDOUT в файл.

В файл попадет список путей ко всем найденным файлам, а список ошибок отобразится в терминале.

Запись STDOUT в файл

Символ — затирает все его содержимое и вставляет значение из потока, поэтому будьте осторожны при правке системных файлов используя данный символ. Если Вам нужно добавить данные в конец файла — используйте два последовательных символа — .

>> — вывод STDOUT в конец файла.

В конец файла  попадет список путей ко всем найденным файлам, а список ошибок отобразится в терминале.

Запись STDOUT в конец файла

>& — вывод STDOUT и STDERR в файл

С помощью составного символа — мы объединяем стандартный выходной поток с выходным потоком ошибок. В файл попадет список путей ко всем найденным файлам и список ошибок.

Объединение выходных потоков

2> — вывод STDERR в файл

В файл попадет список ошибок, а список найденных файлов, будет выведен в терминале.

Вывод STDERR

Вывод потоков можно комбинировать и распределять по разным местам. Например, выведем список найденных файлов в , а список ошибок отбросим, перенаправив их в .

Перенаправление потоков

Для того чтобы направить выходной поток одной команды на входной поток другой, применяют символ — (pipe).

Для примера, выведем в консоли отдельные процессы системы с именем — .

Здесь результат выполнения команды передается в роли входных данных для команды , в которых она ищет совпадения с именем .

Перенаправление

Перед выполнением команды его ввод и вывод могут быть перенаправлены с использованием специальной нотации, интерпретируемой оболочкой. Перенаправление также может использоваться для открытия и закрытия файлов для текущей среды выполнения оболочки. Следующие операторы перенаправления могут предшествовать или появляться в любой точке простой команды или могут следовать за командой. Перенаправления обрабатываются в том порядке, в котором они появляются, слева направо.

Каждому перенаправлению, которому может предшествовать номер дескриптора файла, может предшествовать слово формы { varname } . В этом случае для каждого оператора перенаправления, кроме > & — и <& — , оболочка будет выделять файловый дескриптор более 10 и назначить ему имя varname . Если > & — или <& — предшествует { varname } , значение varname определяет дескриптор файла для закрытия.

В следующих описаниях, если номер дескриптора файла опущен, а первым символом оператора перенаправления является < , перенаправление относится к стандартному вводу (дескриптор файла 0). Если первым символом оператора перенаправления является > , перенаправление относится к стандартным выводам (дескриптор файла 1).

Слово, следующее за оператором перенаправления, в следующих описаниях, если не указано иначе, подвергается расширению скобки, расширению тильды, расширению параметров, замене команд, арифметическому расширению, сокращению цитат, расширению пути и разбиению слов. Если он расширяется до более чем одного слова, bash сообщает об ошибке.

Перенаправление вывода

Перенаправление вывода вызывает файл, имя которого является результатом расширения слова, которое нужно открыть для записи в дескрипторе файла n , или стандартный вывод (дескриптор файла 1), если n не указано. Если файл не существует, он создается; если он существует, он усекается до нулевого размера.

Добавление перенаправленного вывода

Перенаправление вывода таким образом вызывает файл, имя которого является результатом расширения слова, которое нужно открыть для добавления в дескриптор файла n , или стандартный вывод (дескриптор файла 1), если n не указано. Если файл не существует, он создается.

The getchar() and putchar() Functions

The int getchar(void) function reads the next available character from the screen and returns it as an integer. This function reads only single character at a time. You can use this method in the loop in case you want to read more than one character from the screen.

The int putchar(int c) function puts the passed character on the screen and returns the same character. This function puts only single character at a time. You can use this method in the loop in case you want to display more than one character on the screen. Check the following example −

#include <stdio.h>
int main( ) {

   int c;

   printf( "Enter a value :");
   c = getchar( );

   printf( "\nYou entered: ");
   putchar( c );

   return 0;
}

When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads only a single character and displays it as follows −

$./a.out
Enter a value : this is test
You entered: t

DESCRIPTION top

       Under normal circumstances every UNIX program has three streams
       opened for it when it starts up, one for input, one for output, and
       one for printing diagnostic or error messages.  These are typically
       attached to the user's terminal (see tty(4)) but might instead refer
       to files or other devices, depending on what the parent process chose
       to set up.  (See also the "Redirection" section of sh(1).)

       The input stream is referred to as "standard input"; the output
       stream is referred to as "standard output"; and the error stream is
       referred to as "standard error".  These terms are abbreviated to form
       the symbols used to refer to these files, namely stdin, stdout, and
       stderr.

       Each of these symbols is a stdio(3) macro of type pointer to FILE,
       and can be used with functions like fprintf(3) or fread(3).

       Since FILEs are a buffering wrapper around UNIX file descriptors, the
       same underlying files may also be accessed using the raw UNIX file
       interface, that is, the functions like read(2) and lseek(2).

       On program startup, the integer file descriptors associated with the
       streams stdin, stdout, and stderr are 0, 1, and 2, respectively.  The
       preprocessor symbols STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO
       are defined with these values in <unistd.h>.  (Applying freopen(3) to
       one of these streams can change the file descriptor number associated
       with the stream.)

       Note that mixing use of FILEs and raw file descriptors can produce
       unexpected results and should generally be avoided.  (For the
       masochistic among you: POSIX.1, section 8.2.3, describes in detail
       how this interaction is supposed to work.)  A general rule is that
       file descriptors are handled in the kernel, while stdio is just a
       library.  This means for example, that after an exec(3), the child
       inherits all open file descriptors, but all old streams have become
       inaccessible.

       Since the symbols stdin, stdout, and stderr are specified to be
       macros, assigning to them is nonportable.  The standard streams can
       be made to refer to different files with help of the library function
       freopen(3), specially introduced to make it possible to reassign
       stdin, stdout, and stderr.  The standard streams are closed by a call
       to exit(3) and by normal program termination.

Installation

Clone this repository:

Important: In all cases below make sure that path to is absolute!

Linux and FreeBSD

Make sure you have cmake and the gcc toolchain required for compilation installed:

Build:

Export variable in your shell’s config file by putting following
in your .bashrc/.zshrc:

Multi-arch Linux and FreeBSD

On some Linux distros you can install 32-bit packages on 64-bit system. Shared
libraries compiled for 64-bit doesn’t work with 32-bit binaries though. It
happens that 64-bit binaries call 32-bit ones resulting in warning message
printed to terminal about not compatible shared lib.

Fortunately Linux’s dynamic linker has a feature called Dynamic String Token
(DST). It allows dynamic substitution of token in variable
with «lib» or «lib64» respectively for 32 and 64-bit binaries when the binary
is being run. Thanks to that you can compile stderred for both architectures
and automatically use proper version of this shared library.

On 64-bit Fedora, for example, you need to install libc development headers for
both architectures:

compile it like this:

and export like this in your shell’s config:

OSX

Export variable in your shell’s config file by putting following
in your .bashrc/.zshrc:

Universal lib on OSX

OSX solves multi-arch problem (described above in «Multi-arch Linux and
FreeBSD») by supporting so called «universal» libraries that include 2 copies
of code compiled for both 32 and 64-bit architecture in the single library
file.

If you feel you will want universal library then build it this way:

and export shell env like above.

«Jola» should be printed in red color.

The gets() and puts() Functions

The char *gets(char *s) function reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF (End of File).

The int puts(const char *s) function writes the string ‘s’ and ‘a’ trailing newline to stdout.

NOTE: Though it has been deprecated to use gets() function, Instead of using gets, you want to use fgets().

#include <stdio.h>
int main( ) {

   char str;

   printf( "Enter a value :");
   gets( str );

   printf( "\nYou entered: ");
   puts( str );

   return 0;
}

When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads the complete line till end, and displays it as follows −

$./a.out
Enter a value : this is test
You entered: this is test

Перенаправление ввода

Вы можете использовать перенаправление stdin для передачи содержимого текстового файла команде, подобной этой:

command < file

Вы не увидите, что stdin часто используется. Это потому, что большинство команд Linux принимают имена файлов в качестве аргумента и, следовательно, перенаправление stdin часто не требуется.

Возьмите это к примеру:

head < filename.txt

Приведенная выше команда могла быть просто заголовком filename.txt (без <).

Дело не в том, что перенаправление stdin совершенно бесполезно. Некоторые команды полагаются на это. Возьмите команду tr, например. Эта команда может многое, но в приведенном ниже примере она преобразует входной текст из нижнего в верхний регистр:

tr a-z A-Z < filename.txt

На самом деле, использование stdin рекомендуется по конвейеру, чтобы избежать ненужного использования команды cat.

Например, многие люди используют приведенный выше пример с cat, а затем используют tr на нем. Честно говоря, здесь нет необходимости использовать cat.

cat filename.txt | tr a-z A-Z

Stdin, stdout и stderr

Когда вы запускаете команду Linux, в ней играют роль три потока данных:

  • Стандартный ввод ( stdin ) является источником входных данных. По умолчанию стандартный ввод – это любой текст, введенный с клавиатуры. Идентификатор потока равен 0.
  • Стандартный вывод ( stdout ) является результатом команды. По умолчанию он отображается на экране. Идентификатор потока равен 1.
  • Стандартная ошибка ( stderr ) – это сообщение об ошибке (если есть), генерируемое командами. По умолчанию stderr также отображается на экране. Идентификатор потока равен 2.

Эти потоки содержат данные в виде простого текста в том, что называется буферной памятью.

Думайте об этом как о струе воды. Вам нужен источник для воды, например, кран. Вы подключаете к нему трубу и можете хранить ее в ведре (файле) или поливать растения (распечатывать). Вы также можете подключить его к другому крану, если это необходимо. По сути, вы перенаправляете воду.

В Linux также существует такая концепция перенаправления, при которой вы можете перенаправить stdin, stdout и stderr из обычного места назначения в другой файл или команду (или даже на периферийные устройства, такие как принтеры).

Позвольте нам показать, как работает перенаправление и как вы можете его использовать.

Перенаправление вывода

Первой и самой простой формой перенаправления является перенаправление вывода, также называемое перенаправлением stdout.

Вы уже знаете, что по умолчанию вывод команды отображается на экране. Например, мы используем команду ls для вывода списка всех файлов, и это вывод, который мы получаем:

andreyex@destroyer:~$ ls
appstxt  new.txt  static-ip.txt

С перенаправлением вывода вы можете перенаправить вывод в файл. Если эти выходные файлы не существуют, оболочка создаст их.

command > file

Например, позвольте нам сохранить вывод команды ls в файл с именем output.txt:

andreyex@destroyer:~$ ls > output.txt

Выходной файл создается заранее

Как вы думаете, каким должно быть содержимое этого выходного файла? Позвольте нам использовать команду cat, чтобы показать вам сюрприз:

andreyex@destroyer:~$ cat output.txt 
appstxt
new.txt
output.txt
static-ip.txt

Вы заметили, что включение output.txt существует ? Мы сознательно выбрали этот пример, чтобы показать вам это.

Выходной файл, на который перенаправляется стандартный вывод, создается до запуска намеченной команды. Почему? Потому что он должен иметь готовый выходной пункт назначения, на который будут отправлены выходные данные.

Добавить вместо удаления

Одна из часто игнорируемых проблем заключается в том, что если вы перенаправляете файл, который уже существует, оболочка сначала удалит ( замкнет ) файл. Это означает, что существующее содержимое выходного файла будет удалено и заменено выводом команды.

Вы можете добавить вместо перезаписи, используя >> синтаксис перенаправления.

command >> file

Совет
Вы можете запретить забивание в текущем сеансе оболочки, используя: set -C

Зачем вам перенаправлять стандартный вывод? Вы можете сохранить выходные данные для дальнейшего использования и проанализировать их позже. Это особенно полезно, когда вывод команды слишком велик и занимает весь экран. Это как собирать бревна.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector