Bash: перенаправить в файл, всегда создавать новые


8

В bash, командная ссылка

echo test > actual.txt

заменит содержимое файла с именем actual.txt«test» и создаст файл, если он не существует. Однако, если файл существует, bash просто откроет его, урежет и запишет новое содержимое в файл.

В частности, команда redirect терпит неудачу в этом сценарии:

ln -s /some/illegal/path link.txt
echo test > link.txt

Bash 4.4.12 выдает мне запутанное сообщение об ошибке link.txt: No such file or directory.

Один из способов избежать этого - обязательно удалить файл перед запуском перенаправленной команды.

rm link.txt && echo test > link.txt

Мне было интересно, хотя, был ли некоторый трюк опций bash или оператора перенаправления, который предотвратит этот режим сбоя. Любые идеи?


Что если link.txtэто ссылка на файл /dir/fileгде /dirнаходится директория типа, для которой у вас есть разрешение на запись и поиск, но /dir/fileона не существует (и перенаправление создаст ее без сообщения об ошибке)? А что если /dir/fileсуществует, но не является обычным файлом (устройство, fifo, каталог ...), или у вас нет разрешения на запись в него или разрешения на поиск /dir?
Стефан Шазелас

Ответы:


7

Попытка записи на неработающую символическую ссылку эквивалентна попытке записи по несуществующему пути. Нет никакого способа «настроить» перенаправление вывода для создания пути (включая промежуточные каталоги) bash, и нет параметров оболочки, bashкоторые делают это автоматическим.

Если промежуточный путь существует, а конечная точка ссылки отсутствует, то он будет создан путем перенаправления.

Вы можете сделать что-то вроде

if [ -h file ] && [ ! -f file ]; then
    rm file
fi

проверить, является ли «файл» символической ссылкой ( -h) и ссылается ли он на обычный файл, который существует ( -f). Если это символическая ссылка, но она не относится к файлу, то вы удаляете ее.


1
Суть моего вопроса была в том, что я не пытаюсь писать ни к чему. Я хочу создать новый файл с именем link.txt, и там же находится символическая ссылка в том же месте. Чтобы поставить это в виде вопроса: зачем беспокоиться о тестировании, если я собираюсь перезаписать файл на следующей строке? Я могу просто сделать, rm -fи это будет иметь тот же эффект.
itadok

3
@itsadok Ах. Да. Простое выполнение rm -f filenameперед записью на него с перенаправлением также решит вашу проблему. Но это также зависит от того, хотите ли вы, чтобы он находился в текущем каталоге или в каталоге, где расположена конечная точка символической ссылки.
Кусалананда

Вы все еще можете не иметь прав доступа к rmфайлу или записи в него. Как и во многих случаях, вы не можете подготовиться ко всему. Вам необходимо оценить, какие случаи вы действительно ожидаете (если даже в редких случаях), и, следовательно, разобраться, какие случаи вы считаете настолько маловероятными, что вы намеренно их не обрабатываете, и признать, что будет определенное количество случаев, которые вы не рассматриваете, и таким образом, не может справиться.
Алфе
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.