Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run sudo commands in Haskell

I am having ghc 6.12.3 and Ubuntu 11.04 installed on my laptop.

I would like to have a function which take some shell commands and execute them as the superuser (like sudo update-manager, sudo iwlist ....) in Haskell. I know that the System.Process module have some functions like createProcess, runInteractiveCommand. But there are for a single raw command or a single shell command, not for compound commnads like "sudo update-manager". All my experiments on those functions to execute "sudo ..." failed. The terminal I used to run my haskell function had no response.

I also looked at HSH package. But it seems to me that functions exported there are not good for sudo commands either.

My guess is that executing commands like "sudo update-manager" requires two process. One is for "sudo" and the other one is for "update-manager". So I need to call functions like "createProcess" twice and somehow connect them so that the second process for "update-manager" get superuser privilege from the first process for "sudo".

Thanks in advance for help!

like image 309
chenxicali Avatar asked Jul 20 '11 15:07

chenxicali


3 Answers

Try readProcess from System.Process

readProcess :: FilePath -- command to run 
-> [String]             -- any arguments 
-> String               -- standard input 
-> IO String            -- stdout 

readProcess forks an external process, reads its standard output strictly, blocking until the process terminates, and returns the output string.

Run it like this:

readProcess "/usr/bin/sudo" ("-S":someProgram) (passwort++"\n")

This executes sudo with the options -S and the program. -S is needed to read the password from stdin. The password must finish with a newline, so the program adds one.

like image 130
fuz Avatar answered Nov 18 '22 10:11

fuz


Answering the last paragraph. sudo is a regular program, no magic whatsoever. It just happens to run other programs. So does your Haskell program. Your program runs sudo and sudo runs update-manager So no, you should not create two processes.

like image 37
n. 1.8e9-where's-my-share m. Avatar answered Nov 18 '22 10:11

n. 1.8e9-where's-my-share m.


Have you tried System.Process.system?

import System.Process

main = system "sudo update-manager"

This works for me (GHC 7.0.3). Also, for scripting in Haskell in general (sudo included), you can have a look at a presentation "Practical Haskell: scripting with types" by Don Stewart.

like image 41
Antti Avatar answered Nov 18 '22 10:11

Antti