Python invokes shell commands. What type of shell is running?

I have the following python function that allows me to run shell commands from 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, what type of shell is running? (e.g. login vs interactive ).

Knowing which shell is running will help you find out which dot files (e.g. .bashrc , .profile , etc.) are executed before my shell command.

+4
source share
3 answers

Which shell is starting up?

This is stated in the Python subprocess documentation :

The executable file argument indicates the executable program. This is very rarely necessary: ​​usually the executable program is specified by the args argument. If shell = True, the executable argument indicates 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 need to specify shell=True on Windows is where the command you want to execute is really built into the shell, for example, dir, copy. You do not need the shell = True to run the batch file or to run the console-based executable.

/bin/sh on Linux / MacOSX is usually an alias for bash (or bash -compatible - newer versions of Debian using dashes), while on Unix, like Solaris, it can be a classic Bourne shell.

For Windows, usually cmd or command.bat .

Enter the shell or not through popen ?

I just realized that I did not answer your second question, but setting shell=True will generate a non-login shell (see the link to the source code @AndiDog, the way the shell gets forked will create a shell without login).


Safety implications

Also keep in mind that using shell=True , although it allows you to use primitives and shortcuts for the shell, can also be a security risk , so be sure to check any possible inputs that you can use to spawn the process.

Warning Executing shell commands that include unanimated input from an untrusted source makes the program vulnerable to shell injection, a serious security issue that could lead to arbitrary command execution. For this reason, the use of shell = True is very discouraged in cases where the command line is built 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 functions, but does not suffer from this vulnerability; see the note in the Popen constructor documentation for useful tips on how to make shell = False work.

+4
source

This is /bin/sh on POSIX. See Source Code subprocess.py (citing Python 2.7 here):

 def _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, 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 [...] 
+8
source

This is not a login shell, so you are not getting .login, etc.

If for any reason you need to initialize a shell that considers it an input shell, you will need to execute the shell yourself and (I believe that this is still how it is done) change the first character argv [0] it sees "-".

+1
source

Source: https://habr.com/ru/post/1399456/


All Articles