Назад | Перейти на главную страницу

Рекомендации по предотвращению использования 'rm -rf /' в сценариях bash

Хорошо известно, что лишнее пространство в env.variable может привести к удалению каталога / в сценарии bash.

#!/bin/bash
...
rm -rf /$MYPATH

если $ MYPATH содержит такие значения, как "реж" или "dir /" это приведет к "rm -rf / dir" или "rm -rf dir /". И приведет к "rm -rf /"

Есть ли какие-нибудь передовые методы предотвращения такой ситуации?

alias rm='rm --preserve-root'

IIRC --preserve-root используется по умолчанию в новых версиях coreutils.

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

rm -rf "/$FOO" не будет удалять /, если в $ FOO есть начальный пробел, вместо этого вы просто ничего не удалите. Это требует, чтобы кавычки присутствовали в строке с rm -rf, конечно, не что-то вроде:

TODEL="/$FOO"
rm -rf $TODEL

Если вы это сделаете который, ты вернешься к целому ряду неприятностей.

Кроме того, я склонен думать, что это хорошо:

if [ -d "/$FOO" ] ; then
    ...
fi

(Или -e если это просто файл) всегда рекомендуется перед удалением чего-либо.

Перво-наперво: сделайте резервные копии. :-)

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

Вы также можете добавить файл с именем -i в важные каталоги, поэтому в некоторых ситуациях rm будет предлагать при попытке их удалить. Конечно, если вы выполняете удаление каким-либо другим способом, например Perl-скриптом, или даже с другими параметрами rm, это не поможет.

Также можно установить неизменный пометить важные файлы и каталоги с помощью chattr +i, но будьте осторожны с этим. Это может вас укусить, если вы на самом деле должен удалить файлы из некоторого каталога или изменить файлы ...

Один из способов избежать этой проблемы - использовать ОС, которая не позволяет такой команде работать по дизайну, поскольку она, возможно, несовместима с POSIX. Он был инициирован Solaris 10 (2005 г.), затем BSD, а затем Gnu rm в 2006 г.

Сначала проверьте свой код. Серьезно, все, что вам скажут, будет чем-то вроде проверки, которую вы должны были сделать внутри своего кода, чтобы проверить значение $ MYPATH. Если сценарий выполняется в интерактивном режиме, вы можете удалить -f.

Вы можете обрезать MYPATH перед выполнением команды rm. Просто используйте эхо:

MYPATH=`echo $MYPATH`

После неприятного инцидента много лет назад на ящике Ultrix, где я как root userdel -r sccs (или эквивалент Ultrix, это было давно) без предварительной проверки того, какой домашний каталог пользователя sccs был, и $ HOME пользователя sccs оказался /, и файловая система ушла, я избегал размещения rm -rf $ANYTHING в скриптах. Вы можете проверять переменную, пока не посинете, но вместо этого я обычно распечатываю сообщение типа «если вас устраивает идея, теперь вы должны запустить sudo rm -rf $ANYTHING".

Вы можете передать MYPATH через sed и проверить, что то, что вы вводите, совпадает с тем, что вы получаете

MYPATH1=`echo "$MYPATH" | sed -e 's|[ \t]\/[ \t]| |' -e 's|^/[ \t]| |' -e 's|[ \t]/$| |' `
if [ "$MYPATH" != "$MYPATH1" ]
then
    dosomething 
fi

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