Вопрос: Как заставить rm не выдавать ошибку, если файл не существует?


Я пишу makefile, который очистит некоторые бесполезные файлы в конце компиляции. Если цель уже сделана, она, конечно же, пропустит эту цель, и бесполезный файл может отсутствовать. Поэтому, если я это сделаю:

rm lexer.ml interpparse.ml interpparse.mli

Я могу получить ошибки, потому что один из файлов не существует. Есть ли способ сказать rm игнорировать эти файлы?

При чтении man-страницы я вижу следующий вариант:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

Это звучит так: почти что я хочу, но я не уверен в части разрешений. Есть ли способ сделать это?


258
2017-11-27 16:43


Источник


Вы пытались rm в песочнице? Это выглядит как -f делает именно то, что вы хотите, независимо от того, что происходит. - JMD
Если разрешения не позволят, rm будет с -f параметр все еще пытается удалить его. Это провалится. Он не скажет вам, что это не удалось. Полезно, если имя файла является переменной или глобусом. - LawrenceC


Ответы:


-f вариант - это то, что вы хотите использовать.

Подтверждение о разрешении файла, на которое он ссылается, следующее:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

Так rm предупредит вас, если вы попытаетесь удалить файл, на который у вас нет прав на запись. Это разрешено, если у вас есть права на запись в каталоге, но это немного странно, поэтому rm обычно предупреждает вас об этом.


218
2017-11-27 16:54



Большинство, но не все системы будут спрашивать (я думаю). Некоторые требуют -i, - DaveParillo
Если вы хотите, чтобы сообщение об ошибке, но не код выхода с ошибкой, см. Ответ на Giel Berkers, я использую set -e во всех моих сценариях bash, чтобы сценарий вышел после того, как любая команда выдаст ошибку. Я часто хочу, чтобы скрипт говорил мне, если rm дал ошибку, но все равно продолжит. продолжается. - cledoux


Другим решением является следующее: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

Просто добавьте OR-инструкцию после команды:

rm -rf my/dir || true

Таким образом, когда оператор # 1 терпит неудачу (выдает ошибку), запустите оператор # 2, который просто true,


76
2018-03-09 12:39



Он печатает ошибку и продолжает выполнение, которое было желательно для моего случая. - worldsayshi
Или просто rm -rf my/dir ||: быть еще более кратким (: сокращается для true) - Godsmith
Лучшее решение, на мой взгляд. Легко видеть, что происходит, и почему код результата игнорируется. Мне это нравится! - Mavamaarten


Я опаздываю на вечеринку, но я все время использую это. В make-файле добавьте - к началу строки, чтобы игнорировать возвращаемое значение этой строки. Вот так:

-rm lexer.ml interpparse.ml interpparse.mli

68
2017-12-23 23:12



Это все равно выведет ошибку на консоль, хотя и обучает вас игнорировать ошибки в make-файле, что, вероятно, не то, что вы хотите. rm -rf - лучший вариант, на мой взгляд. - Godsmith
@Godsmith Я предпочел бы игнорировать ошибку, чем принудительное удаление рекурсивного удаления. Это может быть очень непослушным. И +1 для синтаксиса конкретного файла makefile - Daishi
Если rm -rf может быть «озорным», это означает, что вы используете make вне каталога под управлением версии. Зачем? - Godsmith
Дайте ссылку на документацию, пожалуйста. Не удалось найти описание этой функции. - George Sovetov
@GeorgeSovetov gnu.org/software/make/manual/make.html#Errors - Robert Li


Если вы не хотите использовать параметр -f, альтернатива:

rm filethatdoesntexist 2> /dev/null 

Это приведет к тому, что ошибки не будут напечатаны.


8
2018-06-12 19:46



К сожалению, это все равно даст код выхода с ошибкой. - Shaun McDonald


Если вы найдете какой-то способ шарик имена файлов, rm не будет жаловаться, если он не сможет найти матч. Так что-то вроде lexer.m* interpparse.*и т. д., должны работать на вас (будьте осторожны, вы, конечно, не слишком много удаляете). Также, -f это вполне разумный путь, если вы не надеетесь, что права на файлы позволят вам удалить файл, который вам не нужен, - если вы не хотите его удалять, не помещайте его в список.


7
2017-11-27 16:48



Глобус не может быть и речи, поскольку есть файл lexer.mll, который я не хочу удалять. Спасибо, что показал, почему -f является разумным. Я полагаю, что я слишком осторожен после того, как слишком много ошибочных sudo rm -rf , - Jason Baker
Даже не более ограничительный lexer.m? ...? Это поймало бы lexer.ml а также lexer.mz, но нет lexer.mll или lexer.mla, - JMD
@JMD: Я полагаю, что это зависит от вашей оболочки и от той поддержки, которую он предлагает для подгонки. - Nick Bastin


Опция -f означает, что вам не будет предложено, если что-то не так, как ожидалось. Это не означает, что разрешения не принимаются во внимание.

Если у вас недостаточно прав для удаления файла, он не будет удален.

НО, если у вас достаточно прав для изменения привилегий, файл будет удален. Это тот случай, когда вы являетесь владельцем файла с правами на чтение для владельца (-r --------). Как владелец, вы можете chmod u+w, затем удалите его: rm -f удалит этот файл.


5
2017-11-27 19:27





Может быть, может помочь строка, похожая на:

touch fakefile.exe fakefile.o && rm *.o *.exe

Я знаю, что это не очень умно, но он выполняет эту работу.


3
2018-03-11 10:36





Альтернатива:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Слишком плохо Makefiles не может делиться определениями функций оболочки по строкам.


2
2017-11-27 17:44



Вы пытались использовать \ (обратная косая черта) в конце строки, чтобы продолжить ее дальше? - some
@ some: Да, они могут быть распределены по нескольким строкам, но чтобы делиться ими по рецептам, вы должны поместить определение в переменную make. - reinierpost


Вот что я использую в сценариях оболочки. Он скрывает сообщение об ошибке и код ошибки.

rm doesnotexist 2> /dev/null || echo > /dev/null

2
2018-06-11 13:55