Верн ли вывод о том, что существует 4 типа **вывода**, на которые мы можем ссылаться применительно к файлу в Linux?

Верн ли вывод о том, что существует 4 типа **вывода**, на которые мы можем ссылаться применительно к файлу в Linux?

Верно ли заключение, что существует 4 типапоток выводаможем ли мы ссылаться на файл в Linux, если мы не хотим, чтобы он отображался в CLI после выполнения команды?

Возможные ссылки на файл:

  1. Весь поток вывода
  2. Только stderr
  3. Только stdout (включая конечный результат stdout).
  4. stdout и stderr (исключая конечный результат stdout).

Примечания:

Примером для номера 4 может быть find / -type f -name php.ini 2>/dev/null. Насколько я понимаю, с помощью этой команды мы не получаем stderr и stdout (кромеОкончательный результат stdoutчто в данном случае является файлом, который мы искали, если он был найден).

решение1

К каждому процессу в системе Unix подключены два выходных потока:стандартный вывод(stdout, файловый дескриптор 1) истандартная ошибка(stderr, file-descriptor 2). Они могут быть перенаправлены независимо друг от друга.Стандартный вводиспользует файловый дескриптор 0.

  • Чтобы перенаправить стандартный вывод в файл file, используйте >fileили более явный вариант 1>file. Замените fileна , /dev/nullчтобы отбросить данные.
  • Чтобы перенаправить стандартную ошибку в файл file, используйте 2>file.
  • Чтобы перенаправить стандартную ошибку туда, куда направляется стандартный вывод, используйте 2>&1.
  • Чтобы перенаправить стандартный вывод туда, куда направляются стандартные ошибки, используйте 1>&2.

Не существует понятия "окончательный результат" потока или процесса. Я полагаю, что все, что отправляется в стандартный вывод, может быть принято как "результат" процесса, если только он также не выводит данные в какой-либо файл, который он открывает сам по себе, или не имеет других побочных эффектов (например, отсоединение файла от каталога, в случае rm, или обработка ряда сетевых подключений, в случае sshd). Процесс также возвращает статус выхода (ноль для "успеха" и ненулевой для "неудачи"), который можно рассматривать как "результат" этого процесса, но это не обязательно связано с выходными потоками процесса.

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

В примечании к вопросу команда

find / -type f -name php.ini 2>/dev/null

дано. Это перенаправляет (отбрасывает)толькостандартная ошибка. Стандартный поток вывода вообще не перенаправляется и, следовательно, будет виден целиком в консоли или терминале. Если бы это была промежуточная часть конвейера, стандартный поток вывода был бы подан в стандартный ввод следующей команды в конвейере.

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

решение2

Каждыйпроцессможет использовать, по соглашению, три стандартных файловых дескриптора. Эти файловые дескрипторы доступны как потоки: stdin, stdout, и stderr.

По умолчанию при запуске процесса из оболочки (CLI) первый подключается к входу вашего терминала (или эмулятора терминала, например xterm), а два других подключаются к выходу вашего терминала.

Вы можете указать оболочке перенаправить их в другое место, например, /dev/null(где они просто будут поглощены). И вы можете сделать это независимо для stdoutи stderr. Так что для этого случая действительно есть четыре возможности:

command 
command > /dev/null
command 2> /dev/null
command > /dev/null 2> /dev/null

Но ничто не мешает вам перенаправить один или оба в другое место:

command > /tmp/myout 2> /tmp/myerr

В этом случае вы также не получите вывод в своем терминале, но сможете прочитать его позже в файлах /tmp/myoutи /tmp/myerr.

решение3

Ситуация проще и сложнее, чем можно предположить из вашего вопроса. Перефразируя то, чтоКусаланандаговорит вего ответ, есть два стандартных (обычных) потока ввода-вывода (файловые дескрипторы), которые традиционно настраиваются и используются для вывода: stdout (файловый дескриптор 1) и stderr (файловый дескриптор 2). Наш канонический вопрос, Каковы операторы управления и перенаправления оболочки?, обсуждает, как перенаправить их. Наивно, мы можем перечислить пять различных комбинаций:

╔══════════════════════════════╦═════════════════════════════════════════════╗
║                              ║                   stderr                    ║
║                              ╟─────────────────────┬───────────────────────╢
║                              ║       default       │                       ║
║                              ║ (same as the shell) │       redirected      ║
╠════════╤═════════════════════╬═════════════════════╦═══════════════════════╣
║        │       default       ║                     ║                       ║
║        │ (same as the shell) ║          1          ║           2           ║
║        ├─────────────────────╠═════════════════════╬═══════════════════════╣
║ stdout │                     ║                     ║ 4. redirected         ║
║        │                     ║                     ║    to the same file   ║
║        │      redirected     ║          3          ╟───────────────────────╢
║        │                     ║                     ║ 5. redirected         ║
║        │                     ║                     ║    to different files ║
╚════════╧═════════════════════╩═════════════════════╩═══════════════════════╝

но если вы считаете /dev/nullего отличным от файла, а режим добавления — особым случаем, а режим чтения-записи — отличным от режима только записи, а каналы — отличными от файлов, то количество комбинаций увеличивается экспоненциально. Однако, как неоднократно говорилось, «окончательный результат stdout» — это не стандартная фраза Unix/Linux/bash.

Только два?

Другие ответы (возможно, благоразумно) ограничились stdout и stderr (файловые дескрипторы 1 и 2). Я (безрассудно?) считаю, что полный ответ на этот вопрос должен учитывать тот факт, что доступны и другие файловые дескрипторы — до сотен, тысяч или дажеболее миллиона. Например, если вы запустите команду типа diff file1 file2, diffпрограмма откроет file1и file2, а ядро, вероятно, назначит дескрипторы файлов 3 и 4. Разница в том, что предопределены только дескрипторы файлов 0, 1 и 2. Перенаправление дескрипторов файлов выше 2 обсуждается в следующих местах:

Например, посмотрите на этот пример высокого дескриптора файла:

$ cat canine.c
#include <stdio.h>
#include <string.h>

основной()
{
        int i, len;
        char msg[] = "Привет, собака.\n";

        len = strlen(сообщение);
        я = запись(17, сообщ, длина);
        если (я == длина)
                printf("Успех! i = %d = len\n", i);
        иначе если (i == -1)
            {
                printf("Ошибка! i = %d (len = %d)\n", i, len);
                ошибка("");
            }
        еще
                printf("Неожиданный результат: i = %d, len = %d\n", i, len);
}

$ сделать собаку
cc собачий.c -o собачий

$ ./собачий
Ошибка! i = -1 (len = 12)
Неверный дескриптор файла

$ ./собачий 17> животное
Успех! i = 12 = len

$ ls -l
всего 70
-рв-р--р-- 1мое имя пользователя мое имя группы    12 апр 12 13:36 животное
-rwxr-xr-x 1мое имя пользователя мое имя группы67067 12 апр 13:36 собака
-рв-р--р-- 1мое имя пользователя мое имя группы   358 12 апр 13:36 canine.c

$ кошка животное
Привет, собака.

Предупреждение: я не уверен, что вышеизложенное будет работать для всех версий всех оболочек.

Стандартные программы не записывают в файловые дескрипторы выше 2 (если только они не получили этот файловый дескриптор из ядра, открыв файл, установив сетевое соединение или что-то в этом роде). Но если у вас есть (нестандартная) программа, которая это делает, вы можете перенаправить эти файловые дескрипторы.

А если у вас всего 100 файловых дескрипторов и вы учитываете только то, перенаправлен ли каждый из них или нет, то у вас есть более миллиона (1 000 000 000 000 000 000 000 000 000 000) возможных комбинаций.

Связанный контент