uiop:launch-program fails to run sudo without -S
Hi! I'd like to run a "sudo" command from Common Lisp. The following works: --8<---------------cut here---------------start------------->8--- (uiop:launch-program '("sudo" "-S" "ls" "/root") :input :stream :output *standard-output*) (format (uiop:process-info-input #v1) "MY-PASSWORD~%") (finish-output (uiop:process-info-input #v1)) --8<---------------cut here---------------end--------------->8--- Note that I'm using the "-S" parameter of sudo. From the man page:
Write the prompt to the standard error and read the password from the standard input instead of using the terminal device.
Without it, "sudo" terminate immediately. Somehow, Emacs _does_ support calling the sudo process without the "-S" flag. Try this: --8<---------------cut here---------------start------------->8--- (make-process :name "dummy" :command '("sudo" "ls" "/root")) --8<---------------cut here---------------end--------------->8--- and the "sudo" process is kindly waiting for input in the background. Any idea why that is? Is it be possible to do the same in Common Lisp? Cheers! -- Pierre Neidhardt https://ambrevar.xyz/
Emacs by default allocates a pty for subprocesses. There’s no way to do this portably, as many Lisps don’t support it, so UIOP won’t help you here. If you’re on SBCL and portability is not a concern, you can use sb-ext:run-program with a :pty keyword argument, as described in section 7.7.3 of the SBCL manual. Failing that, it’s probably best to use sudo -S. phoebe
On Jan 12, 2021, at 10:01 AM, Pierre Neidhardt <mail@ambrevar.xyz> wrote:
Hi!
I'd like to run a "sudo" command from Common Lisp. The following works:
--8<---------------cut here---------------start------------->8--- (uiop:launch-program '("sudo" "-S" "ls" "/root") :input :stream :output *standard-output*) (format (uiop:process-info-input #v1) "MY-PASSWORD~%") (finish-output (uiop:process-info-input #v1)) --8<---------------cut here---------------end--------------->8---
Note that I'm using the "-S" parameter of sudo. From the man page:
Write the prompt to the standard error and read the password from the standard input instead of using the terminal device.
Without it, "sudo" terminate immediately.
Somehow, Emacs _does_ support calling the sudo process without the "-S" flag. Try this:
--8<---------------cut here---------------start------------->8--- (make-process :name "dummy" :command '("sudo" "ls" "/root")) --8<---------------cut here---------------end--------------->8---
and the "sudo" process is kindly waiting for input in the background.
Any idea why that is? Is it be possible to do the same in Common Lisp?
Cheers!
-- Pierre Neidhardt https://ambrevar.xyz/
Thanks for the details, this makes sense! :) The problem with -S is that I need to pass it systematically. Worse: I cannot invoke shell scripts that call `sudo' without -S. So instead I ended up adding this to my ~/.slynk.lisp: --8<---------------cut here---------------start------------->8--- (let ((askpass (format nil "~a/.guix-extra-profiles/common-lisp/common-lisp/bin/lxqt-openssh-askpass" (uiop:getenv "HOME")) )) (when (uiop:file-exists-p askpass) (setf (uiop:getenv "SUDO_ASKPASS") askpass))) --8<---------------cut here---------------end--------------->8--- Works perfectly for me now! :) Thanks! -- Pierre Neidhardt https://ambrevar.xyz/
On Tue, 2021-01-12 at 10:15 -0600, Phoebe Goldman wrote:
Emacs by default allocates a pty for subprocesses. There’s no way to do this portably, as many Lisps don’t support it, so UIOP won’t help you here. If you’re on SBCL and portability is not a concern, you can use sb-ext:run-program with a :pty keyword argument, as described in section 7.7.3 of the SBCL manual. Failing that, it’s probably best to use sudo -S.
While it looks like Pierre has his own solution, I thought I would mention this for posterity on the list: "script" is a relatively portable unix command that will allocate a pty for running. If you need a pty on a unix then it's probably your best-bet if you don't want to be tied to sb-ext:run-program.
Thanks for sharing, this could be interesting indeed. How would you run it in SLY or SLIME then? Do you have an example recipe? -- Pierre Neidhardt https://ambrevar.xyz/
On Tue, 12 Jan 2021 19:14:15 +0100 Pierre Neidhardt <mail@ambrevar.xyz> wrote:
Thanks for sharing, this could be interesting indeed. How would you run it in SLY or SLIME then? Do you have an example recipe? Oh, I missed this e-mail somehow. Here's an example:
(with-input-from-string (s (format nil "mypassword~%")) (uiop:run-program '("script" "-c" "sudo ls") :input s :output :string)) Notes: 1. sudo does have "-S" to prevent it from requiring a pty, but this was the original question, so it's what I used. 2. The parameter to "-c" ("sudo ls" above) will be interpreted by the shell.
Thanks for the example! This would work, but as opposed to setting SUDO_ASKPASS as mentioned before, this approach has the drawback that you cannot pass an input to the subcommand. Anyways, one way or another, problem solved! Thanks! -- Pierre Neidhardt https://ambrevar.xyz/
participants (3)
-
Jason Miller
-
Phoebe Goldman
-
Pierre Neidhardt