允许用户仅使用GUI(隐藏终端)为bash脚本输入密码的正确方法

我制作了一个bash脚本,它专门使用kdialog与用户进行交互。 它是从“.desktop”文件启动的,因此用户永远不会看到终端。 它看起来像一个GUI应用程序100% (即使它只是一个bash脚本)。 它仅在KDE中运行(Kubuntu 12.04)。

我唯一的问题是安全方便地处理密码输入 。 我找不到满意的解决方案。

该脚本旨在作为普通用户运行,并在首次需要sudo命令时提示输入密码。 通过这种方式,大多数命令(不需要sudo权限的命令)都以普通用户身份运行。 发生的事情(当从终端运行脚本时)是提示用户输入一次密码,默认的sudo超时允许脚本完成,包括任何其他sudo命令,而不再提示用户。 这也是我希望它在GUI后面运行时的工作方式。

主要问题是使用kdesudo启动我的脚本(这是标准的GUI方式)意味着整个脚本由root用户执行。 所以文件所有权被分配给root用户,我不能依赖~/ in路径,而且很多其他东西都不太理想。 以root用户身份运行整个脚本只是一个非常不理想的解决方案,我认为这是一个不好的做法。

我感谢任何让用户通过GUI输入sudo密码而不以root身份运行整个脚本的想法。 谢谢。

-A sudo选项允许您指定将要求输入密码的帮助程序(在SUDO_ASKPASS变量中)。

创建一个脚本来询问密码(myaskpass.sh):

 #!/bin/bash zenity --password --title=Authentication 

然后在脚本的开头插入此行:

 export SUDO_ASKPASS="/path/to/myaskpass.sh" 

并使用以下sudo 替换sudo 出现:

 sudo -A  

您可以使用您想要的任何密码询问程序而不是zenity 。 我不得不将其封装在脚本中,因为SUDO_ASKPASS必须指向一个文件,所以它不适用于zenity所需的--password选项。

如果从命令行运行,或者如果在文件管理器中双击脚本文件后选择Run in terminal ,则上面的工作就像魅力一样,但如果选择Run或尝试从.desktop文件启动它,则每个sudo都会要求再次输入密码。


如果您根本不需要终端窗口,可以将密码存储在变量中并将其传递给sudo -S 。 也许有一些安全问题,但我认为这是非常安全的(阅读这个答案的评论)。

在脚本的开头插入此行:

 PASSWD="$(zenity --password --title=Authentication)\n" 

并使用以下sudo 替换sudo 出现:

 echo -e $PASSWD | sudo -S  

这是基于Eric Carvalho的优秀答案。 我发布它来详细说明我遇到的问题。 具体地说,当使用它时,通常的sudo超时(例如,15分钟)丢失。 我的脚本有超过50个sudo命令,现在提示用户密码超过50次!

以下是解决方案所有部分的完整工作示例。 它由一个bash脚本,一个Eric建议的“myaskpass”脚本和一个“.desktop”文件组成。 整个事情应该是100%的GUI(根本没有终端交互),所以.desktop文件是必不可少的(afaik)。

 $ cat myaskpass.sh #!/bin/bash kdialog --password "Please enter your password: " exit 0 $ cat askpasstest1.desktop #!/usr/bin/env xdg-open [Desktop Entry] Comment=SUDO_ASKPASS tester1 Exec=bash /home/user/test/askpasstest1.sh GenericName=SUDO_ASKPASS tester1 Name=SUDO_ASKPASS tester1 NoDisplay=false Path[$e]= StartupNotify=true Terminal=false TerminalOptions= Type=Application Categories=Application;Utility; X-KDE-SubstituteUID=false X-KDE-Username= 

还有一个测试脚本本身。 使用此解决方案时,这个将要求您输入两次密码。 (通常,由于默认的sudo超时,它只会询问一次。)

 #!/bin/bash sudo -k SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1 touch filemadeas_regularuser1 SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2 touch filemadeas_regularuser2 ls -la filemadeas* > /home/user/test/fma.log kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480 sudo rm filemadeas_* rm fma.log exit 0 

以下脚本通过命令行,桌面文件或双击工作,只需要输入一次密码,命令模式sudo -Sp '' <<<${sudo_password}可以在任何地方多次使用文件:

  # get sudo password sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null ) # check for null entry or cancellation if [[ ${?} != 0 || -z ${sudo_password} ]] then exit 4 fi if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null then exit 4 fi # command sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}