Я знаю, что опаздываю на вечеринку, но я только что столкнулся с этим. Чтобы увидеть вывод команды, вы можете передать его вzenity
следующим образом:
command | zenity --text-info
Если вы хотите увидеть ошибки,вы можете перенаправить stderr на stdout следующим образом:
command 2>&1 | zenity --text-info
Для этого есть приложение! Команда 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.
еще один способ исправить это — использовать метод записи без усечения
rev a | dd conv=notrunc of=a
это работает только потому, что:
rev считывает содержимое перед созданием вывода, и вывод никогда не длиннее уже прочитанного объема
содержимое нового файла имеет такой же размер или больше исходного (в данном случае тот же размер)
Этот подход может быть полезен для -изменения места в файлах, слишком больших для хранения временных копий.
Вы можете использовать Vim в режиме Ex:
ex -s -c '%!rev' -c x a.txt
%
выбрать все линии !
команда запуска x
сохранить и закрыть >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
Причины были объяснены другими, но в основном та же самая причина, по которой вы не можете:
rev a >a
Но как это сделать?:
echo foo >a
echo `cat a | rev` >a
# or
echo `rev a` >a