Wildman via Python-list <python-list@python.org> writes: > Python 2.7.9 on Linux > > Here is a bash command that I want to run from a python > program: sudo grep "^user\:" /etc/shadow
Some points to note: * Those commands are not special to Bash, or any particular shell. They invoke commands, without AFAIK any specific Bash features. So this is asking rather to invoke a shell command. Nothing wrong with that; but on that basis, I've changed the subject field. * You're asking to invoke the ‘sudo’ command, which itself is designed to switch to a separate user identity and run another program. * The above command is (I assume) typed into a shell, but your Python program never invokes Bash or any other shell. > If I enter the command directly into a terminal it works perfectly. Note that ‘sudo’ is specifically designed to be invoked interactively, seeking to verify that the current user has credentials to run the command. Note further that ‘sudo’ will record when the *current user session* last invoked ‘sudo’ and seek re-verification if that is too long in the past. Both of these are security measures, and are designed to avoid non-interactive use of ‘sudo’. Rather, it's meant to be used interactively by a real, present human with credentials to run the command. > If I run it from a python program it returns an empty string. You can also check the exit status of a command; ‘grep’ will give different exit status for a match versus no match. > Below is the code I am using. Suggestions > appreciated. > > cmdlist = ["sudo", "grep", '"^$USER\:"', "/etc/shadow"] One immediate difference I see is that you specify different arguments to ‘grep’. You have a different pattern for each command. * The ‘^user\:’ pattern matches “user\:” at the start of a line. * The ‘^$USER\:’ pattern I think won't match anything, since “$” matches end-of-line and then you expect further characters *past* the end of the line. I think that will always fail to match any line. > p = subprocess.Popen(cmdlist, > stdout=subprocess.PIPE, > stderr=subprocess.PIPE) > shadow, err = p.communicate() Maybe you are expecting Bash to be involved somehow (and so “$USER” will be substituted by Bash with some other value). That's not what happens. Instead, the ‘subprocess.Popen.communicate’ method will invoke the program directly, without involving a shell. See the documentation for ‘subprocess.Popen’. -- \ “If you continue running Windows, your system may become | `\ unstable.” —Microsoft, Windows 95 bluescreen error message | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list