Что делает оболочку интерпретировать эти перенаправления следующим образом?

Может ли кто-нибудь помочь мне понять это, казалось бы, странное поведение того, как оболочка анализирует перенаправления ..?

$ cat > test.txt Line 1 Line 2 $ ls -i dummy.txt dummy2.txt ls: dummy.txt: No such file or directory ls: dummy2.txt: No such file or directory $ $ cat test.txt > dummy.txt > dummy2.txt $ cat dummy2.txt Line 1 Line 2 $ cat dummy.txt $ 

Интересно! Я бы ожидал, что вывод из cat test.txt будет перенаправлен в dummy.txt а затем оболочка будет читать dummy.txt в качестве входа для dummy2.txt . Но как-то оболочка анализирует его по-другому …

Итак, как содержимое test.txt принимается за вход для dummy2.txt , вообще обходя dummy.txt ?


Примечание. Тот же результат в bash и ksh ..

2 Solutions collect form web for “Что делает оболочку интерпретировать эти перенаправления следующим образом?”

Важно знать, что ваша оболочка не перенаправляет вывод , а дескрипторы файлов . Каждый процесс в POSIX-совместимой операционной системе имеет 3 потока ввода-вывода: STDIN, STDOUT и STDERR. Переадресация > перенаправляет дескриптор файла для потока STDOUT. Итак, что видит оболочка при анализе этой строки:

  1. cat test.txt – Хорошо, я запустил cat программы и даю ей аргумент test.txt
  2. > dummy.txt – О, теперь я возьму дескриптор STDOUT процесса cat и подключу его к этому файлу под названием «dummy.txt». Мне все равно, если что-то было раньше, я создам файл и обрезаю его до нуля.
  3. > dummy2.txt – О, теперь я возьму дескриптор STDOUT процесса cat (который я ранее подключил к «dummy.txt») и подключил его к другому новому файлу. Я не могу обойти обе вещи, потому что вы перенаправляете, а не дублируете дескрипторы файлов.

Вот почему эта команда:

 find / 2>&1 >/dev/null 

приводит к выходу ошибки в STDOUT, и нет регулярного выхода (STDOUT), но этот:

 find / >/dev/null 2>&1 

результаты не выводят вообще. В первом случае мы помещаем STDERR на копию (dup) STDOUT, а затем ставим старый STDOUT в корзину. Во втором мы сначала помещаем STDOUT в корзину, затем копируем его (все еще указываем на /dev/null ) и ставим также STDERR.

От комментариев к ответу, хотя некоторые из них – это спекуляция:

Если вы запустите в bash,

 cat test.txt > d1 > d2 > d3 > d4 > d5 

то от d1 до d4 будет пусто, а содержимое test.txt будет в d5. Кажется, что Bash выполняет фактическое перенаправление только для указанного последнего файла.

Любопытно, что zsh (по крайней мере, версия 5) скопирует содержимое test.txt во все файлы-посредники.

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

Конкретная часть страницы руководства выглядит следующим образом:

 Note that the order of redirections is significant. For example, the command ls > dirlist 2>&1 directs both standard output and standard error to the file dirlist, while the command ls 2>&1 > dirlist directs only the standard output to file dirlist, because the standard error was duplicated from the standard output before the standard output was redirected to dirlist. 

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

Я уверен, что кто-то скоро будет исправлять любые дикие (или мягкие) ошибки в этой спекуляции 🙂

  • Два IP-адреса на одном интерфейсе, узнайте, какой из них используется
  • Автоматизация труб?
  • выполнение скрипта после выхода из системы
  • Сценарий Bash для запуска виртуальной среды python не выполняется
  • Динамически присваивать массив значению переменной. Eval?
  • Что значит иметь в скрипте строку $ msign-prefixed?
  • Как извлечь строку из имени файла?
  • Как предотвратить повторное уведомление по электронной почте с помощью bash
  • Как я могу перенаправить вывод дочернего процесса?
  • Запуск исполняемого файла с помощью скрипта оболочки
  • как обращаться с аргументами при выполнении скрипта
  • Interesting Posts

    Как вызвать предыдущую команду (без выполнения), чтобы ее изменить?

    Языковая переменная отсутствует после обновления

    Какой PID входит в раздел systemd PIDFile при создании демона сценария оболочки?

    Является ли `/ etc / X11 / xorg.conf` устаревшим?

    Всесторонний сценарий /etc/auto.disks для autofs, который учитывает все смонтированные диски, включая NTFS и FAT32?

    Запустить псевдоним после создания

    как обновить прошивку ноутбука на Linux

    Получил «синтаксическую ошибку около неожиданного конца файла» в сценарии bash

    Измените каталог с пробелом, за которым следует '('

    Сервер SVN с удаленным администрированием графического интерфейса

    Почему безопаснее предоставлять права sudo для пользователя без root?

    При выборе из меню не выполнить задачу?

    Сортировка и резервное копирование файлов log4j

    Может ли дерево команд UNIX отображать только каталоги, соответствующие шаблону?

    Замена точек в имени файла символами подчеркивания, кроме расширения

    Linux и Unix - лучшая ОС в мире.