Изучаем Bash. Как не отправить все в /dev/null
2 minutes read in LinuxВ скрипте инициализации RHEL допущена ошибка, приводящая к удалению всех файлов
Не делать assert’ов в критических точках приложения – отличный способ выстрелить в ногу с рикошетом в голову.
Пример из новости выше:
stop
rm -rf $SQUID_PIDFILE_DIR/*
start
Без контекста заметить проблему трудно, но точно известно если переменная SQUID_PIDFILE_DIR не будет определена мы выполним:
rm -rf /*
Веселого в этом мало, a для того чтобы избежать таких ситуаций (которые могут легко возникнуть в большом BASH скрипте) нужно было использовать следующую проверку:
stop
[ -z "$SQUID_PIDFILE_DIR" ] || exit 42
rm -rf $SQUID_PIDFILE_DIR/*
start
При таком подходе мы бы никогда не вызвали команду rm на корне файловой системы.
Про контрактное программирование на Java можно почитать здесь.
Bonus: ShellCheck
ShellCheck – замечательная тулза, обязательна для использования как начинающими, так и продолжающмим скрипто писателями.
Чтобы показать полезность, прогоним кусок показанный выше, через ShellCheck:
$ cat myscript.sh
rm -rf $SQUID_PIDFILE_DIR/*
$ shellcheck myscript.sh
Line 1:
rm -rf $SQUID_PIDFILE_DIR/*
^-- SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
^-- SC2115: Use "${var:?}" to ensure this never expands to /* .
^-- SC2086: Double quote to prevent globbing and word splitting.
$
Как видите, ShellCheck указала на целых две проблемы в простейшем коде. Также можно почитать подробнее про каждый варнинг:
Выводы:
- Bash коварен
- Не пишите на Bash
- Если все же пишите, используйте ShellCheck