如何在后台运行需要输入密码的 sudo 命令?

如何在后台运行需要输入密码的 sudo 命令?

我最近禁用了sudo的身份验证缓存能力所以现在每次都会提示我输入密码。

虽然这对于安全性有好处,但它却引起了一个小问题,我还没能找到解决办法,我无法运行如下命令:

sudo <command> &

过去,我会sudo在那之前运行一个命令,它会缓存我的密码,并允许我sudo在接下来的几分钟内无需提示即可运行命令,因此它允许我运行该命令。
但是当我现在运行它时,由于事先没有缓存,并且它会立即启动一个新线程,甚至sudo不会提示我输入密码,所以我无法以这种方式运行它。

因此,除非我sudo -i在此之前运行,否则我无法运行这种格式的命令,这变得相当烦人。
所以我想知道是否有办法解决这个问题并仍然以这种方式运行程序和命令?

我正在运行带有 GNOME 3.18 的 Ubuntu GNOME 15.10,具体来说,我想要以这种方式运行的程序etherape是否有任何区别,但我真的希望该解决方案适用于所有程序和命令。

答案1

sudo不要在后台运行,而是告诉sudo在后台运行命令。从man sudo

-b, --background
     Run the given command in the background.  Note that it is not
     possible to use shell job control to manipulate background
     processes started by sudo.  Most interactive commands will
     fail to work properly in background mode.

例如:

sudo -b sleep 10

另一种方法是仅使用 shell 运行命令:

sudo sh -c 'sleep 10 &'

另一种选择是指定一个图形程序来获取密码,然后发送sudo到后台:

-A, --askpass
     Normally, if sudo requires a password, it will read it from
     the user's terminal.  If the -A (askpass) option is
     specified, a (possibly graphical) helper program is executed
     to read the user's password and output the password to the
     standard output.  If the SUDO_ASKPASS environment variable is
     set, it specifies the path to the helper program.  Otherwise,
     if sudo.conf(5) contains a line specifying the askpass
     program, that value will be used.  For example:

         # Path to askpass helper program
         Path askpass /usr/X11R6/bin/ssh-askpass

     If no askpass program is available, sudo will exit with an
     error.

Askpass 程序通常用于 SSH。ssh-askpass-gnome软件包中提供了一个这样的程序,默认情况下会安装,至少在 Ubuntu 15.10 上是如此。

SUDO_ASKPASS=/usr/bin/ssh-askpass sudo -A sleep 10 &

答案2

如果您愿意timestamp_timeout至少设置为0.02(1.2 秒,我认为与 一样安全0/etc/sudoers(在您的情况下是需要的,但使用默认设置或timestamp_timeout设置为任何值,但0可以执行以下操作),您可以设置一个像这样的别名~/.bashrc,它不需要您记住在运行命令之前做一些事情,并且可以让您保持对进程的控制。:

alias sudo='sudo -v; [ $? ] && sudo'

这里的技巧是分号,它将使 Bashsudo -v首先单独进行解析,对用户进行身份验证,并将潜在的后台部分限制为命令[ $? ] && sudo,它将检查是否sudo -v成功,如果成功则sudo再次运行(可能将其后台化)。

$ alias sudo='sudo -v; [ $? ] && sudo'
$ sudo -H gedit &
[sudo] password for user:
[1] 19966
$ jobs
[1]+  Running                 [ $? ] && sudo -H gedit &

答案3

不能。 会&立即将命令发送到后台。也就是说,会在后台创建一个子 shell,并在那里执行命令。当该命令发出提示符时(例如 的情况)sudo,提示符会在后台显示,您永远看不到它。

解决该问题的唯一方法是将命令带回前台,提供密码并将其发送回后台。例如:

$ sudo command &
$ fg
sudo command
[sudo] password for terdon: 

现在,输入您的密码,点击Enter,然后点击CtrlZ将其发送回后台并bg告诉它继续运行。

一种更简单的方法是永远不要使用作业,而是在启动作业时和启动后&手动将其发送到后台。CtrlZbg

最后,您可能需要考虑将 sudo 的密码超时设置为 1 或 2 秒。这仍然可以为您提供足够的安全性(除非您试图防范 Flash),并允许您按预期运行此类命令。

相关内容