Изгиб конвейера обратно в исходное положение.

Я знаю, что опаздываю на вечеринку, но я только что столкнулся с этим. Чтобы увидеть вывод команды, вы можете передать его вzenityследующим образом:

command | zenity --text-info

Если вы хотите увидеть ошибки,вы можете перенаправить stderr на stdout следующим образом:

command 2>&1 | zenity --text-info

24
27.12.2019, 11:22
5 ответов

Для этого есть приложение! Команда spongeиз moreutilsпредназначена именно для этого. Если вы используете Linux, он, скорее всего, уже установлен, если не искать в репозиториях вашей операционной системы spongeили moreutils. Затем вы можете сделать:

echo foo >a
cat a | rev | sponge a

Или, избегая UUoC:

rev a | sponge a

Причиной такого поведения является порядок, в котором выполняются ваши команды. > aна самом деле выполняется первым, и > fileочищает файл. Например:

$ echo "foo" > file
$ cat file
foo
$ > file
$ cat file
$

Итак, когда вы запускаете cat a | rev >a, на самом деле происходит то, что сначала запускается > a, очищая файл, поэтому, когда выполняется cat a, файл уже пуст. Именно поэтому spongeбыло написано (от man sponge, курсив мой ):

.

sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before writing the output file. This allows constructing pipelines that read from and write to the same file.

32
27.01.2020, 19:40

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

  rev a | dd conv=notrunc of=a

это работает только потому, что:

  1. rev считывает содержимое перед созданием вывода, и вывод никогда не длиннее уже прочитанного объема

  2. содержимое нового файла имеет такой же размер или больше исходного (в данном случае тот же размер)

  3. dd открывает файл для записи, не усекая его.

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

8
27.01.2020, 19:40

Вы можете использовать Vim в режиме Ex:

ex -s -c '%!rev' -c x a.txt
  • %выбрать все линии
  • !команда запуска
  • xсохранить и закрыть
0
27.01.2020, 19:40

>fileсоздать новый пустой файл или обрезать существующий файл. Таким образом, в файле revнечего читать.


Как упоминалось в других ответах, вы можете использовать для этого sponge. Но spongeдоступен не всем.

Ниже приводится общее решение, включающее только оболочку.:

exec 3<file; rm file; rev <&3 >file; exec 3<&-

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

Далее выполняется revчтение из "удаленного файла". Его вывод отправляется в новый файл. Хотя этот новый файл имеет то же имя, что и исходный файл, это другой файл. Как такового конфликта нет.

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


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

( rev file >file.new && mv file.new file ) || rm file.new
1
14.05.2020, 05:14

Причины были объяснены другими, но в основном та же самая причина, по которой вы не можете:

rev a >a

Но как это сделать?:

echo foo >a
echo `cat a | rev` >a
# or
echo `rev a` >a
0
14.05.2020, 05:53

Теги

Похожие вопросы