Спасибо ответившим. Конечный ответ, который я реализовал, таков... Я нашел в другом месте на этом сайте подпрограмму для сравнения паролей с /etc/shadow.
Поскольку я использую графический интерфейс, я использую zenity для запроса пароля. Человек на RPi не знает свой пароль из-за автологина. После ввода пароля он преобразуется в хэш с использованием соли из учетной записи пользователя и сравнивается сгенерированный хеш и исходный хэш. Если они совпадают, то запускается терминальная программа.
Если нажать кнопку отмены zenity или ввести неверный пароль, ничего не происходит.
Для запуска скрипта, которому нужны разрешения для grep файла /etc/shadow, у меня есть запись в /etc/sudoers.d/myfile = UserA ALL= (ALL )NOPASSWD :/ opt/myFiles/startTerminal.sh
Скрипт:
USERNAME=UserA
PASSWD=$(zenity --forms --title=" " \
--text="Enter Password" \
--add-password="" )
if [[ $? -eq 0 ]]; then
export PASSWD
ORIGPASS=`grep -w "$USERNAME" /etc/shadow | cut -d: -f2`
export ALGO=`echo $ORIGPASS | cut -d'$' -f2`
export SALT=`echo $ORIGPASS | cut -d'$' -f3`
GENPASS=$(perl -le 'print crypt("$ENV{PASSWD}","\$$ENV{ALGO}\$$ENV{SALT}\$")')
if [ "$GENPASS" == "$ORIGPASS" ]; then
/usr/bin/lxterminal &
exit 0
fi
fi
Вы можете использовать sprintf
для вывода нового значения в форматированную строку и назначения его в качестве нового значения$2
:
$2 = sprintf("%.15f",1-$2)
Тогда остается просто напечатать всю (измененную )запись:
$ awk '{$2 = sprintf("%.15f",1-$2); print}' file
752566 0.116071428571429 1 rs3094315 0
752721 0.234126984126984 1 rs3131972 0
752894 0.116071428571429 1 rs3131971 0
753541 0.731150793650794 1 rs2073813 0
Это должно быть awk?
$ cat in
752566 0.883928571428571 1 rs3094315 0
752721 0.765873015873016 1 rs3131972 0
752894 0.883928571428571 1 rs3131971 0
753541 0.268849206349206 1 rs2073813 0
$ perl -pe 's/(\d+\.\d+)/sprintf("%.15f", 1-$1)/e' < in
752566 0.116071428571429 1 rs3094315 0
752721 0.234126984126984 1 rs3131972 0
752894 0.116071428571429 1 rs3131971 0
753541 0.731150793650794 1 rs2073813 0
Мы можем использовать команду калькулятора dc
. Ширина точности хранится в переменной $precsn с точностью по умолчанию, установленной на 6. Поскольку порядок вывода не обязательно должен совпадать, мы печатаем в обратном порядке из-за природы LiFO dc.
precsn=15
sed -Ee 's/\S+/[&]/4' file |
dc -e "
${precsn:-6}k
[q]sq
[n32anz2<p]sp
[?z0=q lpx 1r-1/0 nn32an pcz0=?]s?
l?x
"
0 rs3094315 1 0.116071428571429 752566
0 rs3131972 1 0.234126984126984 752721
0 rs3131971 1 0.116071428571429 752894
0 rs2073813 1 0.731150793650794 753541