Этот вопрос похож на Какой самый безопасный способ очистки каталога в * nix?
Я пишу скрипт bash, который определяет несколько констант пути и будет использовать их для манипулирования файлами и каталогами (копирование, переименование и удаление). Часто нужно будет сделать что-то вроде:
rm -rf "/${PATH1}"
rm -rf "${PATH2}/"*
При разработке этого скрипта я хотел бы защитить себя от опечаток, таких как PATH1 и PATH2, и избежать ситуаций, когда они раскрываются в пустую строку, что приводит к очистке всего диска. Я решил создать специальную обертку:
rmrf() {
if [[ $1 =~ "regex" ]]; then
echo "Ignoring possibly unsafe path ${1}"
exit 1
fi
shopt -s dotglob
rm -rf -- $1
shopt -u dotglob
}
Который будет называться:
rmrf "/${PATH1}"
rmrf "${PATH2}/"*
Regex (или выражение sed) должно перехватывать пути типа "*", "/ *", "/ ** /", "/// *" и т. Д., Но разрешать пути типа "dir", "/ dir", "/ dir1 / dir2 /", "/ dir1 / dir2 / *". Также я не знаю, как включить глобирование оболочки в случае, как "/ dir с пробелом * *". Есть идеи?
РЕДАКТИРОВАТЬ: это то, что я придумал до сих пор:
rmrf() {
local RES
local RMPATH="${1}"
SAFE=$(echo "${RMPATH}" | sed -r 's:^((\.?\*+/+)+.*|(/+\.?\*+)+.*|[\.\*/]+|.*/\.\*+)$::g')
if [ -z "${SAFE}" ]; then
echo "ERROR! Unsafe deletion of ${RMPATH}"
return 1
fi
shopt -s dotglob
if [ '*' == "${RMPATH: -1}" ]; then
echo rm -rf -- "${RMPATH/%\*/}"*
RES=$?
else
echo rm -rf -- "${RMPATH}"
RES=$?
fi
shopt -u dotglob
return $RES
}
Использование по назначению (обратите внимание на звездочку внутри цитаты):
rmrf "${SOMEPATH}"
rmrf "${SOMEPATH}/*"
, где $ SOMEPATH не является системным или / home каталогом (в моем случае все такие операции выполняются в файловой системе, смонтированной в каталоге / scratch).
ПРЕДОСТЕРЕЖЕНИЯ:
- не проверено очень хорошо
- не предназначен для использования с путями, возможно содержащими '..' или '.'
- не следует использовать с указанными пользователем путями
- rm -rf со звездочкой, вероятно, может завершиться ошибкой, если в $ SOMEPATH слишком много файлов или каталогов (из-за ограниченной длины командной строки) - это можно исправить с помощью цикла for или find