Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python calling shell commands. What type of shell is started?

Tags:

python

shell

I have the following python function that allows me to run shell commands from within a python script:

import subprocess   

def run_shell_command(cmd,cwd=None):
      retVal = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, cwd=cwd);
      retVal = retVal.stdout.read().strip('\n');
      return(retVal);

This allows me to do things like:

output = run_shell_command("echo 'Hello world'")

My question is: with the definition of run_shell_command above, which type of shell is started? (e.g. login vs interactive).

Knowing which shell is started would help know which which dot files (e.g. .bashrc, .profile, etc.) are executed prior to my shell command.

like image 379
Amelio Vazquez-Reina Avatar asked Mar 02 '12 19:03

Amelio Vazquez-Reina


3 Answers

It's /bin/sh on POSIX. See the source code subprocess.py (quoting Python 2.7 here):

def _execute_child(self, args, executable, preexec_fn, close_fds,
                   cwd, env, universal_newlines,
                   startupinfo, creationflags, shell, to_close,
                   p2cread, p2cwrite,
                   c2pread, c2pwrite,
                   errread, errwrite):
    """Execute program (POSIX version)"""

    if isinstance(args, types.StringTypes):
        args = [args]
    else:
        args = list(args)

    if shell:
        args = ["/bin/sh", "-c"] + args
        if executable:
            args[0] = executable
    [...]
like image 197
AndiDog Avatar answered Sep 21 '22 00:09

AndiDog


What shell is run?

This is mentioned in the Python subprocess documentation:

The executable argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the args argument. If shell=True, the executable argument specifies which shell to use. On Unix, the default shell is /bin/sh. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.

/bin/sh on Linux/MacOSX is typically an alias for bash (or bash-compatible - newer versions of Debian use dash), whereas on Unixes like Solaris, it might be classic Bourne Shell.

For Windows, it's usually cmd or command.bat.

Login shell or not via popen?

I just realized that I haven't answered your 2nd question - but setting shell=True will spawn a non-login shell (look @AndiDog's source code link, the way the shell is getting forked would create a non-login shell).


Security Implications

Also be aware that using shell=True, while it allows you to use shell primitives and shortcuts, can also be a security risk, so be sure to check any possible inputs you might use for process spawning.

Warning Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input:

>>>
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False disables all shell based features, but does not suffer from this vulnerability; see the Note in the Popen constructor documentation for helpful hints in getting shell=False to work.

like image 38
逆さま Avatar answered Sep 18 '22 00:09

逆さま


It's not a login shell, so you don't get .login etc.

If for any reason you need to initialize a shell that thinks it's a login shell, you'll need to execute the shell yourself and (I believe this is still how this is done) change the first character of the argv[0] it sees to be a "-".

like image 24
alexis Avatar answered Sep 18 '22 00:09

alexis