Подтвердить что ты не робот

Использование того же файла для stdin и stdout с перенаправлением

Я пишу приложение, которое действует как фильтр: он читает ввод из файла (stdin), обрабатывает и записывает вывод в другой файл (stdout). Входной файл полностью считывается до того, как приложение начнет запись выходного файла.

Поскольку я использую stdin и stdout, я могу запустить, как это:

$ ./myprog <file1.txt >file2.txt

Он отлично работает, но если я пытаюсь использовать тот же файл, что и вход и выход (то есть: чтение из файла и запись в тот же файл), например:

$ ./myprog <file.txt >file.txt

он очищает file.txt, прежде чем программа имеет возможность прочитать его.

Есть ли способ сделать что-то подобное в командной строке в Unix?

4b9b3361

Ответ 1

Оболочка - это то, что захватывает ваш выходной файл, поскольку он готовит дескрипторы выходных файлов перед выполнением вашей программы. Нет способа заставить вашу программу читать ввод до того, как оболочка скроет файл в одной командной строке оболочки.

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

mv file.txt filecopy.txt
./myprog < filecopy.txt > file.txt

Или вывести копию и затем заменить оригинал:

./myprog < file.txt > filecopy.txt
mv filecopy.txt file.txt

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

./myprog file.txt                 # reads and writes according to its own rules

Ответ 2

В утилите moreutils имеется утилита sponge:

./myprog < file.txt | sponge file.txt

Процитировать руководство:

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

Ответ 3

Для решения чисто академического характера:

$ ( unlink file.txt && ./myprog >file.txt ) <file.txt

Возможно, проблемные побочные эффекты:

  • Если ./myprog терпит неудачу, вы уничтожаете свой вход. (Естественно...)
  • ./myprog выполняется из подоболочки (используйте { ... ; } вместо ( ... ), чтобы этого избежать.)
  • file.txt становится новым файлом с новыми правами доступа к файлам и файлам.
  • Вам нужно разрешение +w на корпус каталога file.txt.