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