标签云

微信群

扫码加入我们

WeChat QR Code

How do you call an external command (as if I'd typed it at the Unix shell or Windows command prompt) from within a Python script?


Is there a way to use variable substitution? IE I tried to do echo $PATH by using call(["echo", "$PATH"]), but it just echoed the literal string $PATH instead of doing any substitution. I know I could get the PATH environment variable, but I'm wondering if there is an easy way to have the command behave exactly as if I had executed it in bash.

2019年10月21日20分42秒

KevinWheeler You should NOT use shell=True, for this purpose Python comes with os.path.expandvars. In your case you can write: os.path.expandvars("$PATH"). SethMMorton please reconsider your comment -> Why not to use shell=True

2019年10月20日20分42秒

To simplify at least conceptually:\n call("ls -l".split())

2019年10月20日20分42秒

If you want to create a list out of a command with parameters, a list which can be used with subprocess when shell=False, then use shlex.split for an easy way to do this docs.python.org/2/library/shlex.html#shlex.split

2019年10月21日20分42秒

you forgot to say it needs python 3.5 at least. It doesn't work on python 3.4.3 for example, which is default for Ubuntu 14.04 LTS

2019年10月20日20分42秒

Nice answer/explanation.How is this answer justifying Python's motto as described in this article ?fastcompany.com/3026446/…"Stylistically, Perl and Python have different philosophies. Perl’s best known mottos is " There’s More Than One Way to Do It". Python is designed to have one obvious way to do it"Seem like it should be the other way! In Perl I know only two ways to execute a command - using back-tick or open.

2019年10月20日20分42秒

If using Python 3.5+, use subprocess.run(). docs.python.org/3.5/library/subprocess.html#subprocess.run

2019年10月21日20分42秒

What one typically needs to know is what is done with the child process's STDOUT and STDERR, because if they are ignored, under some (quite common) conditions, eventually the child process will issue a system call to write to STDOUT (STDERR too?) that would exceed the output buffer provided for the process by the OS, and the OS will cause it to block until some process reads from that buffer. So, with the currently recommended ways, subprocess.run(..), what exactly does "This does not capture stdout or stderr by default." imply? What about subprocess.check_output(..) and STDERR?

2019年10月21日20分42秒

Pitto yes, but that is not what gets executed by the example. Notice the echo in front of the string passed to Popen? So the full command will be echo my mama didnt love me && rm -rf /.

2019年10月21日20分42秒

This is arguably the wrong way around. Most people only need subprocess.run() or its older siblings subprocess.check_call() et al. For cases where these do not suffice, see subprocess.Popen(). os.popen() should perhaps not be mentioned at all, or come even after "hack your own fork/exec/spawn code".

2019年10月20日20分42秒

.readlines() reads all lines at once i.e., it blocks until the subprocess exits (closes its end of the pipe). To read in real time (if there is no buffering issues) you could: for line in iter(p.stdout.readline, ''): print line,

2019年10月20日20分42秒

Could you elaborate on what you mean by "if there is no buffering issues"?If the process blocks definitely, the subprocess call also blocks.The same could happen with my original example as well. What else could happen with respect to buffering?

2019年10月20日20分42秒

the child process may use block-buffering in non-interactive mode instead of line-buffering so p.stdout.readline() (note: no s at the end) won't see any data until the child fills its buffer. If the child doesn't produce much data then the output won't be in real time. See the second reason in Q: Why not just use a pipe (popen())?. Some workarounds are provided in this answer (pexpect, pty, stdbuf)

2019年10月20日20分42秒

the buffering issue only matters if you want output in real time and doesn't apply to your code that doesn't print anything until all data is received

2019年10月20日20分42秒

This answer was fine for its time, but we should no longer recommend Popen for simple tasks. This also needlessly specifies shell=True. Try one of the subprocess.run() answers.

2019年10月20日20分42秒

i noticed a possible "quirk" with developing py2exe apps in pydev+eclipse. i was able to tell that the main script was not detached because eclipse's output window was not terminating; even if the script executes to completion it is still waiting for returns. but, when i tried compiling to a py2exe executable, the expected behavior occurs (runs the processes as detached, then quits). i am not sure, but the executable name is not in the process list anymore. this works for all approaches (os.system("start *"), os.spawnl with os.P_DETACH, subprocs, etc.)

2019年10月20日20分42秒

you might also need CREATE_NEW_PROCESS_GROUP flag. See Popen waiting for child process even when the immediate child has terminated

2019年10月20日20分42秒

The following is incorrect: "[o]n windows (win xp), the parent process will not finish until the longtask.py has finished its work". The parent will exit normally, but the console window (conhost.exe instance) only closes when the last attached process exits, and the child may have inherited the parent's console. Setting DETACHED_PROCESS in creationflags avoids this by preventing the child from inheriting or creating a console. If you instead want a new console, use CREATE_NEW_CONSOLE (0x00000010).

2019年10月20日20分42秒

I didn't mean that executing as a detached process is incorrect. That said, you may need to set the standard handles to files, pipes, or os.devnull because some console programs exit with an error otherwise. Create a new console when you want the child process to interact with the user concurrently with the parent process. It would be confusing to try to do both in a single window.

2019年10月20日20分42秒

is there not an OS-agnostic way to have the process run in the background?

2019年10月21日20分42秒

If you want to create a list out of a command with parameters, a list which can be used with subprocess when shell=False, then use shlex.split for an easy way to do this docs.python.org/2/library/shlex.html#shlex.split (it's the recommended way according to the docs docs.python.org/2/library/subprocess.html#popen-constructor)

2019年10月21日20分42秒

This is incorrect: "it does shell escaping for you and is therefore much safer". subprocess doesn't do shell escaping, subprocess doesn't pass your command through the shell, so there's no need to shell escape.

2019年10月20日20分42秒

popen is deprecated in favor of subprocess.

2019年10月20日20分42秒

You can also save your result with the os.system call, since it works like the UNIX shell itself, like for example os.system('ls -l > test2.txt')

2019年10月20日20分42秒

What do you mean by "the command isn't cleaned"?

2019年10月21日20分42秒

No idea what I meant nearly a decade ago (check the date!), but if I had to guess, it would be that there's no validation done.

2019年10月20日20分42秒

This should now point to subprocess as a slightly more versatile and portable solution. Running external commands is of course inherently unportable (you have to make sure the command is available on every architecture you need to support) and passing user input as an external command is inherently unsafe.

2019年10月20日20分42秒

Note the timestamp on this guy: the "correct" answer has 40x the votes and is answer #1.

2019年10月20日20分42秒

Note that check_output requires a list rather than a string. If you don't rely on quoted spaces to make your call valid, the simplest, most readable way to do this is subprocess.check_output("ls -l /dev/null".split()).

2019年10月20日20分42秒

Passing commands as strings is normally a bad idea

2019年10月20日20分42秒

I think it's acceptable for hard-coded commands, if it increases readability.

2019年10月20日20分42秒

commands is no longer available in Python 3. You should prefer subprocess over os.system()

2019年10月20日20分42秒

While I agree with the overall recommendation, subprocess does not remove all of the security problems, and has some pesky issues of its own.

2019年10月20日20分42秒

Further, with subprocess you have to import yet another package to do a simple thing.

2019年10月21日20分42秒

Astrid you have to import a package regardless (i.e. import os)

2019年10月20日20分42秒

A simple example of two-way communication between a primary process and a subprocess can be found here: stackoverflow.com/a/52841475/1349673

2019年10月20日20分42秒

The first example should probably have shell=True or (better yet) pass the command as a list.

2019年10月20日20分42秒

it's also deprecated.use subprocess

2019年10月20日20分42秒

This fails to point out the drawbacks, which are explained in much more detail in PEP-324. The documentation for os.system explicitly recommends avoiding it in favor of subprocess.

2019年10月20日20分42秒

This duplicates a (slightly) more detailed answer from the previous April, which however also fails to point out the caveats.

2019年10月20日20分42秒

What do you mean by "Anyone runs the kwrite not being a subprocess"?

2019年10月21日20分42秒

ts is not standard on any distro I know of, though the pointer to at is mildly useful. You should probably also mention batch. As elsewhere, the os.system() recommendation should probably at least mention that subprocess is its recommended replacement.

2019年10月20日20分42秒