Intereting Posts
Как получить номер дескриптора файла для вывода и как перенаправить все из них сразу Не удается найти ОС Windows и ее разделы со всеми данными Как правильно проверить отравление кэша арп локально Debian Stretch / Gnome – экран моего ноутбука просто повернут; нужно вернуться к нормальной жизни Как навсегда установить переменные среды Документ, который будет отображаться в Интернете с использованием любого веб-сервера Linux Двойная загрузка Mint / Windows: потеряна 8 ГБ на стороне Windows Добавить вывод в файл и перенаправить stderr в null В чем разница между sh и ./ при вызове сценария оболочки? объединение двух файлов в соответствии с указанной строкой Как я могу узнать, работает ли команда с трубой? Перенаправление вывода при выполнении «bash -c …» из программы C MySQL устанавливает прерывания с ошибкой Файлы, записанные в гостевой системе QEMU через VirtIO / 9p, принадлежат пользователю libvirt-qemu Команда tshark для нахождения MAC указанной сети

Помогите мне понять, почему тест $? -eq 0 истинно, даже если я ожидаю, что оно будет ложным

все еще борясь с этим сценарием оболочки (проверка пароля), я искал решение, но я все еще не нашел подходящего решения.

#!/bin/sh echo "enter the password" read password len="${#password}" if test $len -ge 8 ; then echo "$password" | grep -q [AZ] echo "$password" | grep -q [az] echo "$password" | grep -q [0-9] if test $? -eq 0 ; then echo "Strong password" else echo "Weak password" fi else echo "password lenght should be greater than or equal 8" fi 

Результат этого скрипта был следующим:

 # ./password.sh enter the password 12345678 Strong password >> Not as I expected which is should be weak password 

Где моя вина?

Ваши вызовы grep запускаются последовательно и $? равен только последнему grep в вашем скрипте. После каждого grep вы захотите использовать что-то подобное:

 retCodes=0 echo "$password" | grep -q "[AZ]" retCodes=$(($retCodes + $?)) echo "$password" | grep -q "[az]" retCodes=$(($retCodes + $?)) echo "$password" | grep -q "[0-9]" retCodes=$(($retCodes + $?)) 

Значение if [[ $retCodes -eq 0 ]]; then ... if [[ $retCodes -eq 0 ]]; then ...

Несколько вещей:

  • Использование read без -r затрудняет наличие \ в пароле.

  • Не цитирование регулярных выражений заставит оболочку рассматривать их как шаблоны глобусов, и они будут расширяться до имен файлов.

  • $? переменная будет удерживать только статус выхода последнего grep .

Рассмотрим следующий сценарий bash :

 #!/bin/bash read -r -p "password:" -s password if (( ${#password} < 8 )); then echo "Passwords need 8 or more characters" exit 1 fi has_upcase=0 has_locase=0 has_digit=0 has_other=0 case "$password" in *[[:upper:]]*) has_upcase=1 ;;& *[[:lower:]]*) has_locase=1 ;;& *[[:digit:]]*) has_digit=1 ;;& *[^[:alnum:]]*) has_other=1 ;; esac if (( !has_upcase )); then echo "Make sure you password has at least one upper-case letter" elif (( !has_locase )); then echo "Make sure your password has at least one lower-case letter" elif (( !has_digit )); then echo "Make sure your password has at least one digit" elif (( !has_other )); then echo "Make sure your password has at least non-alphanumeric character" else echo "Your password is ok" fi 

Я взял на себя смелость добавить «не-алфавитно-цифровое» требование к тестированию.

read bash может дать пользователю подсказку и читать, не повторяя того, что набирается.

В заявлении case проверяется, содержит ли введенный пароль хотя бы один верхний регистр, один строчный, один численный и один не-буквенно-цифровой символ (с использованием классов символов POSIX ). Напуганный вид ;;& в конце каждой строки означает «продолжить тестирование следующего шаблона с помощью этой строки».

Чтобы получить вариант POSIX sh , замените

 stty -echo printf "password: " read -r password stty echo printf "\n" 

А case с чем-то вроде

 case "$password" in *[[:upper:]]*) has_upcase=1 ;; esac case "$password" in *[[:lower:]]*) has_locase=1 ;; esac case "$password" in *[[:digit:]]*) has_digit=1 ;; esac case "$password" in *[^[:alnum:]]*) has_other=1 ;; esac 

Остальное должно быть POSIX.

Может быть, это поможет:

 #!/bin/sh echo "enter the password" read -r password caps="$(echo "$password" | sed 's/[^AZ]//g')" lowers="$(echo "$password" | sed 's/[^az]//g')" numbers="$(echo "$password" | sed 's/[^0-9]//g')" if [ "${#password}" -lt 8 ]; then echo "password lenght should be greater than or equal 8" else echo "caps=${#caps} lowers=${#lowers} numbers=${#numbers}" if [ "${#caps}" -ge 1 ] && [ "${#lowers}" -ge 1 ] && [ "${#numbers}" -ge 1 ]; then echo "Strong password" else echo "Weak password" fi fi