2015-05-17 2 views
2

Я пытаюсь выполнить следующую команду в UNIX.Почему file2 пустой после 'cat file1> file2> file3'?

$ cat file1>file2>file3 

В сценарии, где только file1 присутствует, то, что я думаю, что должно случиться:

  • file2 должен быть создан с содержанием file1,
  • , а затем file3 от содержания file2 ,

Что на самом деле происходит то, что:

  • file2 и file3 получить создан и
  • file3 имеет содержание file1
  • но file2 не - file2 создан, но он пустой/пустой ,

Может ли кто-нибудь объяснить, почему это происходит?

ответ

2

strace дает ответ.

open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 
dup2(3, 1)      = 1 
close(3)       = 0 
open("file3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 
dup2(3, 1)      = 1 
close(3)       = 0 
execve("/bin/cat", ["cat", "file1"], [/* 38 vars */]) = 0 

Второй dup2() закрывает файловый дескриптор, связанный с файлом2. Когда cat работает, его stdout - file3.

1

Что происходит, как управлять стандартным вводом/выводом.

Вы cat file1>file2>file3 и то, что он делает здесь почти такой же, как

cat file1 > file3 

Поскольку file2 имеет его вход перенаправляются на выход

Таким образом, даже если ваш file2 имеет некоторый текст это и вы выполните

cat file1 > file2 > file3 

Содержимое файла3 будет по-прежнему содержать содержимое файла1, почему?

CAT (1) Пользователь Команды CAT (1)

ИМЯ кот - конкатенации файлов и печать на стандартный вывод

ОПИСАНИЕ Concatenate файл (ы), или стандартный ввод, к стандартному выходу.

Проверьте или (или стандартного ввода на стандартный вывод). Вы перенаправляете стандартный ввод из файла2 непосредственно на стандартный вывод.

Давайте supose такой сценарий:

  • file1 содержит '123'
  • file2 содержит «456
  • file3 не существует

Если вы cat file1 > file2 > file3 то содержимое из файлы будут

  • file1 содержит '123'
  • file2 является пустой
  • file3 содержит '123'

file2 отправить к выходу, что FILE1 отправить на вход

+0

'file2' всегда будет пустым после команды, так как перенаправление очистит его. –

+0

Вы правы. Я ошибся в команде, когда тестировал и выполнял 'cat file1 >> file2> file3', поэтому я думал, что он все равно сохранит свой контент – AlvaroAV

6

Оболочка интерпретирует переадресацию файлов слева направо перед запуском команды. Поэтому, когда вы входите

cat file1 > file2 > file3 

это первый делает переадресацию > file2 - создание или опорожнение file2 и указывая на него стандартный вывод. Затем он делает > file 3, создавая или опорожняя file3 и указывая там stdout. Наконец, он выполняет команду cat file1, которая читает file1 и копирует ее в стандартный вывод. Поскольку stdout (сейчас) указывает на file3, file3 заканчивается тем, что является копией этого. Поскольку ничего не было записано в stdout, когда он указывал на file2, file2 заканчивается пустым.

4

Другие объяснили, почему file2 пусто (но, лаконично, это происходит потому, что перенаправление file3 заменяет перенаправление file2, так file2 создается или опорожняется, но file3 получает данные из file1).

Если вы хотите вывод в виде двух файлов, используйте tee:

cat file1 | tee file2 > file3 

Есть другие способы сделать это, в том числе:

tee < file1 file2 > file3 

, который имеет определенную симметрию приятную для него. Он также избегает тега UUoC (бесполезное использование cat), к которому открыт другой. Однако, если у вас было переменное количество входных файлов (0 или стандартный ввод, или много - значение более одного - или вам нужно было обработать аргументы командной строки), то cat все равно будет правильным. Обратите внимание, что tee может генерировать несколько файлов (поэтому в некоторых случаях cat "[email protected]" | tee file1 file2 file3 >/dev/null может иметь смысл).

Смежные вопросы