Popen read error

Execute a child program in a new process. On POSIX, the class uses os.execvp()-like behavior to execute the child program. On Windows, the class uses the Windows CreateProcess() function. The arguments to Popen are as follows.

Execute a child program in a new process. On POSIX, the class uses
os.execvp()-like behavior to execute the child program. On Windows,
the class uses the Windows CreateProcess() function. The arguments to
Popen are as follows.

args should be a sequence of program arguments or else a single string.
By default, the program to execute is the first item in args if args is
a sequence. If args is a string, the interpretation is
platform-dependent and described below. See the shell and executable
arguments for additional differences from the default behavior. Unless
otherwise stated, it is recommended to pass args as a sequence.

On POSIX, if args is a string, the string is interpreted as the name or
path of the program to execute. However, this can only be done if not
passing arguments to the program.

Note

shlex.split() can be useful when determining the correct
tokenization for args, especially in complex cases:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

Note in particular that options (such as -input) and arguments (such
as eggs.txt) that are separated by whitespace in the shell go in separate
list elements, while arguments that need quoting or backslash escaping when
used in the shell (such as filenames containing spaces or the echo command
shown above) are single list elements.

On Windows, if args is a sequence, it will be converted to a string in a
manner described in Converting an argument sequence to a string on Windows. This is because
the underlying CreateProcess() operates on strings.

The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.

On POSIX with shell=True, the shell defaults to /bin/sh. If
args is a string, the string specifies the command
to execute through the shell. This means that the string must be
formatted exactly as it would be when typed at the shell prompt. This
includes, for example, quoting or backslash escaping filenames with spaces in
them. If args is a sequence, the first item specifies the command string, and
any additional items will be treated as additional arguments to the shell
itself. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

On Windows with shell=True, the COMSPEC environment variable
specifies the default shell. The only time you need to specify
shell=True on Windows is when the command you wish to execute is built
into the shell (e.g. dir or copy). You do not need
shell=True to run a batch file or console-based executable.

Note

Read the Security Considerations section before using shell=True.

bufsize will be supplied as the corresponding argument to the
open() function when creating the stdin/stdout/stderr pipe
file objects:

  • 0 means unbuffered (read and write are one
    system call and can return short)
  • 1 means line buffered
    (only usable if universal_newlines=True i.e., in a text mode)
  • any other positive value means use a buffer of approximately that
    size
  • negative bufsize (the default) means the system default of
    io.DEFAULT_BUFFER_SIZE will be used.

Changed in version 3.3.1: bufsize now defaults to -1 to enable buffering by default to match the
behavior that most code expects. In versions prior to Python 3.2.4 and
3.3.1 it incorrectly defaulted to 0 which was unbuffered
and allowed short reads. This was unintentional and did not match the
behavior of Python 2 as most code expected.

The executable argument specifies a replacement program to execute. It
is very seldom needed. When shell=False, executable replaces the
program to execute specified by args. However, the original args is
still passed to the program. Most programs treat the program specified
by args as the command name, which can then be different from the program
actually executed. On POSIX, the args name
becomes the display name for the executable in utilities such as
ps. If shell=True, on POSIX the executable argument
specifies a replacement shell for the default /bin/sh.

stdin, stdout and stderr specify the executed program’s standard input,
standard output and standard error file handles, respectively. Valid values
are PIPE, DEVNULL, an existing file descriptor (a positive
integer), an existing file object, and None. PIPE
indicates that a new pipe to the child should be created. DEVNULL
indicates that the special file os.devnull will be used. With the
default settings of None, no redirection will occur; the child’s file
handles will be inherited from the parent. Additionally, stderr can be
STDOUT, which indicates that the stderr data from the applications
should be captured into the same file handle as for stdout.

If preexec_fn is set to a callable object, this object will be called in the
child process just before the child is executed.
(POSIX only)

Warning

The preexec_fn parameter is not safe to use in the presence of threads
in your application. The child process could deadlock before exec is
called.
If you must use it, keep it trivial! Minimize the number of libraries
you call into.

Note

If you need to modify the environment for the child use the env
parameter rather than doing it in a preexec_fn.
The start_new_session parameter can take the place of a previously
common use of preexec_fn to call os.setsid() in the child.

If close_fds is true, all file descriptors except 0, 1 and
2 will be closed before the child process is executed. (POSIX only).
The default varies by platform: Always true on POSIX. On Windows it is
true when stdin/stdout/stderr are None, false otherwise.
On Windows, if close_fds is true then no handles will be inherited by the
child process. Note that on Windows, you cannot set close_fds to true and
also redirect the standard handles by setting stdin, stdout or stderr.

Changed in version 3.2: The default for close_fds was changed from False to
what is described above.

pass_fds is an optional sequence of file descriptors to keep open
between the parent and child. Providing any pass_fds forces
close_fds to be True. (POSIX only)

New in version 3.2: The pass_fds parameter was added.

If cwd is not None, the function changes the working directory to
cwd before executing the child. cwd can be a str and
path-like object. In particular, the function
looks for executable (or for the first item in args) relative to cwd
if the executable path is a relative path.

Changed in version 3.6: cwd parameter accepts a path-like object.

If restore_signals is true (the default) all signals that Python has set to
SIG_IGN are restored to SIG_DFL in the child process before the exec.
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.
(POSIX only)

Changed in version 3.2: restore_signals was added.

If start_new_session is true the setsid() system call will be made in the
child process prior to the execution of the subprocess. (POSIX only)

Changed in version 3.2: start_new_session was added.

If env is not None, it must be a mapping that defines the environment
variables for the new process; these are used instead of the default
behavior of inheriting the current process’ environment.

Note

If specified, env must provide any variables required for the program to
execute. On Windows, in order to run a side-by-side assembly the
specified env must include a valid SystemRoot.

If encoding or errors are specified, the file objects stdin, stdout
and stderr are opened in text mode with the specified encoding and
errors, as described above in Frequently Used Arguments. If
universal_newlines is True, they are opened in text mode with default
encoding. Otherwise, they are opened as binary streams.

New in version 3.6: encoding and errors were added.

If given, startupinfo will be a STARTUPINFO object, which is
passed to the underlying CreateProcess function.
creationflags, if given, can be one or more of the following flags:

  • CREATE_NEW_CONSOLE
  • CREATE_NEW_PROCESS_GROUP
  • ABOVE_NORMAL_PRIORITY_CLASS
  • BELOW_NORMAL_PRIORITY_CLASS
  • HIGH_PRIORITY_CLASS
  • IDLE_PRIORITY_CLASS
  • NORMAL_PRIORITY_CLASS
  • REALTIME_PRIORITY_CLASS
  • CREATE_NO_WINDOW
  • DETACHED_PROCESS
  • CREATE_DEFAULT_ERROR_MODE
  • CREATE_BREAKAWAY_FROM_JOB

Popen objects are supported as context managers via the with statement:
on exit, standard file descriptors are closed, and the process is waited for.

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Changed in version 3.2: Added context manager support.

Changed in version 3.6: Popen destructor now emits a ResourceWarning warning if the child
process is still running.

Содержание:

  • Проверка на завершение процесса Popen.poll(),
  • Ожидание завершения процесса Popen.wait(),
  • Взаимодействие с процессом Popen.communicate(),
  • Послать сигнал процессу Popen.send_signal(),
  • Остановить процесс Popen.terminate(),
  • Убить процесс Popen.kill(),
  • Вернуть имя программы со всеми параметрами Popen.args(),
  • Передать данные процессу Popen.stdin(),
  • Извлечь генерируемые данные процессом Popen.stdout(),
  • Извлечь ошибки процесса Popen.stderr(),
  • Посмотреть pid процесса Popen.pid(),
  • Посмотреть код, с которым завершился процесс Popen.returncode().

Методы объекта Popen.

Popen.poll():

Метод Popen.poll() проверяет, завершен ли дочерний процесс. Возвращает атрибут кода возврата Popen.returncode. В противном случае возвращает None.

>>> import time, subprocess
>>> proc = subprocess.Popen(['sleep', '30'])
>>> print(proc.poll())
# None

# после 30 секунд
>>> print(proc.poll())
# 0
>>> proc.returncode
# 0

Popen.wait(timeout=None):

Метод Popen.wait() ждет завершения дочернего процесса. Возвращает атрибут кода возврата Popen.returncode.

>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '10'])
>>> proc.wait()
# 0
>>> proc = subprocess.Popen(['sleep', '10'])
>>> proc.wait(5)
# Traceback (most recent call last):
#     raise TimeoutExpired(self.args, timeout)
# subprocess.TimeoutExpired: Command '['sleep', '10']' timed out after 5 seconds

Примечание:

  • Метод Popen.wait() приведет к взаимоблокировке при использовании stdout=subprocess.PIPE или stderr=subprocess.PIPE если дочерний процесс генерирует достаточно данных для канала. Метод блокирует ожидание буфера канала ОС для приема большего количества данных. Используйте метод Popen.communicate() при использовании каналов, чтобы избежать этого.
  • Метод реализован с использованием цикла занятости (неблокирующий вызов и короткие спящие режимы). Используйте модуль asyncio для асинхронного ожидания.

Popen.communicate(input=None, timeout=None):

Метод Popen.communicate() взаимодействует с процессом, отправляя данные в stdin и читает данные из stdout и stderr, пока не будет достигнут конец файла. Необязательным входным аргументом должны быть данные input, которые будут отправлены дочернему процессу или None, если никакие данные отправлять не требуется.

Метод Popen.communicate() возвращает кортеж (stdout_data, stderr_data). Данные будут строками, если потоки были открыты в текстовом режиме, в противном случае байты.

>>> from subprocess import Popen, PIPE
>>> cmd = ['ls', '-Rla', '/tmp']
>>> proc = Popen(cmd, stdout=PIPE, stderr=PIPE, encoding='utf-8')
>>> stdout, stderr = proc.communicate()
>>> print(stdout)
# /tmp:
# итого 76
# drwxrwxrwt 17 root   root   4096 мая 13 15:06 .
# drwxr-xr-x 26 root   root   4096 апр 30 09:18 ..
# drwxrwxrwt  2 root   root   4096 мая 13 07:35 .font-unix
# drwxrwxrwt  2 root   root   4096 мая 13 07:35 .ICE-unix
# ...
# ...
>>> print(stderr)
# ls: невозможно открыть каталог ... Отказано в доступе
# ls: невозможно открыть каталог ... Отказано в доступе
# ...
# ...
Обратите внимание

, что если необходимо отправить данные в процесс, то нужно создать вызвать subprocess.Popen() с аргументом stdin=subprocess.PIPE. Точно так же, чтобы получить что-то кроме None в кортеже результата, то также нужно указать stdout=subprocess.PIPE и/или stderr=subprocess.PIPE.

Если истекает время ожидания timeout, то дочерний процесс не уничтожается, поэтому для правильной очистки, приложение с хорошим поведением должно завершить дочерний процесс и завершить соединение:

# псевдокод
proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

Примечание:

  • Считываемые данные буферизируются в памяти, поэтому не используйте этот метод, если размер данных большой или неограниченный. В этом случае пишите данные в лог-файл, пример смотрите в разделе «Часто используемые параметры модуля subprocess«.

Popen.send_signal(signal):

Метод Popen.send_signal() посылает сигнал signal дочернему процессу.

>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '60'])
>>> proc.send_signal(9)
>>> proc.poll()
# -9

Примечание:

  • В Windows SIGTERM является псевдонимом Popen.terminate(). CTRL_C_EVENT и CTRL_BREAK_EVENT можно отправлять процессам, запущенным с параметром creationflags, который включает CREATE_NEW_PROCESS_GROUP.

Popen.terminate():

Метод Popen.terminate() останавливает дочерний процесс.

  • В ОС Unix метод отправляет SIGTERM дочернему процессу.
  • В Windows вызывается Win32 API-функция TerminateProcess().
>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '60'])
>>> proc.terminate()
>>> proc.poll()
# -15

Popen.kill():

Метод Popen.kill() убивает дочерний процесс.

  • В ОС Unix функция отправляет SIGKILL ребенку.
  • В Windows метод Popen.kill() является псевдонимом Popen.terminate().
>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '60'])
>>> proc.kill()
>>> proc.poll()
-9

Атрибуты объекта Popen.

Popen.args:

Атрибут Popen.args() возвращает аргумент args в том виде, как он был передан в subprocess.Popen(). Представляет из себя список аргументов программы или отдельная строка.

Popen.stdin:

Если аргумент stdin=subprocess.PIPE, то атрибут Popen.stdin() является записываемым объектом потока, возвращаемым функцией open().

Если были заданы аргументы encoding или errors, или text=True (также известный как universal_newlines), то Popen.stdin() является текстовым потоком, в противном случае это поток байтов.

Если аргумент stdin не был равен subprocess.PIPE, то этот атрибут будет возвращать None.

Предупреждение:

  • Используйте метод Popen.communicate() вместо методов Popen.stdin.write(), чтобы избежать взаимных блокировок из-за того, что другие буферы конвейера ОС заполняют и блокируют дочерний процесс.

Popen.stdout:

Если аргумент stdout=subprocess.PIPE, то атрибут Popen.stdout() является читаемым объектом потока, возвращаемым функцией open(). Чтение из потока stdout обеспечивает вывод генерируемых данных от дочернего процесса.

Если были заданы аргументы encoding или errors, или text=True (также известный как universal_newlines), то Popen.stdout() является текстовым потоком, в противном случае это поток байтов.

Если аргумент stdout не был равен subprocess.PIPE, то этот атрибут будет возвращать None.

Предупреждение:

  • Используйте метод Popen.communicate() вместо метода Popen.stdout.read(), чтобы избежать взаимных блокировок из-за того, что другие буферы конвейера ОС заполняют и блокируют дочерний процесс.

Popen.stderr:

Если аргумент stderr=subprocess.PIPE, то атрибут Popen.stderr() является читаемым объектом потока, возвращаемым open (). Чтение из потока stderr обеспечивает вывод ошибок от дочернего процесса.

Если были заданы аргументы encoding или errors, или text=True (также известный как universal_newlines), то Popen.stderr() является текстовым потоком, в противном случае это поток байтов.

Если аргумент stderr не был равен subprocess.PIPE, то этот атрибут будет возвращать None.

Предупреждение:

  • Используйте метод Popen.communicate() вместо методаPopen.stderr.read(), чтобы избежать взаимных блокировок из-за того, что другие буферы конвейера ОС заполняют и блокируют дочерний процесс.

Popen.pid:

Атрибут Popen.pid() возвращает идентификатор ID процесса дочернего процесса.

>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '10'])
>>> proc.pid
# 6016
Обратите внимание

, что если аргумент shell=True, то это идентификатор процесса порожденный оболочкой.

Popen.returncode:

Атрибут Popen.returncode() это код возврата дочернего процесса, установленный Popen.poll() и Popen.wait() и косвенно — Popen.communicate(). Значение None указывает, что процесс еще не завершен.

Отрицательное значение -N указывает на то, что дочерний элемент был прерван сигналом N. Справедливо только для Unix.

>>> import subprocess
>>> proc = subprocess.Popen(['sleep', '20'])
>>> print(proc.returncode)
# None
>>> proc.terminate()
>>> proc.poll()
# -15
>>> proc.returncode
# -15
Purpose: Spawn and communicate with additional processes.
Available In: 2.4 and later

The subprocess module provides a consistent interface to
creating and working with additional processes. It offers a
higher-level interface than some of the other available modules, and
is intended to replace functions such as os.system(),
os.spawn*(), os.popen*(), popen2.*() and
commands.*(). To make it easier to compare subprocess
with those other modules, many of the examples here re-create the ones
used for os and popen.

The subprocess module defines one class, Popen and a
few wrapper functions that use that class. The constructor for
Popen takes arguments to set up the new process so the parent
can communicate with it via pipes. It provides all of the
functionality of the other modules and functions it replaces, and
more. The API is consistent for all uses, and many of the extra steps
of overhead needed (such as closing extra file descriptors and
ensuring the pipes are closed) are “built in” instead of being handled
by the application code separately.

Note

The API is roughly the same, but the underlying implementation is
slightly different between Unix and Windows. All of the examples
shown here were tested on Mac OS X. Behavior on a non-Unix OS will
vary.

Running External Command¶

To run an external command without interacting with it, such as one
would do with os.system(), Use the call()
function.

import subprocess

# Simple command
subprocess.call(['ls', '-1'], shell=True)

The command line arguments are passed as a list of strings, which
avoids the need for escaping quotes or other special characters that
might be interpreted by the shell.

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py

Setting the shell argument to a true value causes subprocess
to spawn an intermediate shell process, and tell it to run the
command. The default is to run the command directly.

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)

Using an intermediate shell means that variables, glob patterns, and
other special shell features in the command string are processed
before the command is run.

$ python subprocess_shell_variables.py

/Users/dhellmann

Error Handling¶

The return value from call() is the exit code of the program.
The caller is responsible for interpreting it to detect errors. The
check_call() function works like call() except that the
exit code is checked, and if it indicates an error happened then a
CalledProcessError exception is raised.

import subprocess

subprocess.check_call(['false'])

The false command always exits with a non-zero status code,
which check_call() interprets as an error.

$ python subprocess_check_call.py

Traceback (most recent call last):
  File "subprocess_check_call.py", line 11, in <module>
    subprocess.check_call(['false'])
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.
7/subprocess.py", line 511, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['false']' returned non-zero e
xit status 1

Capturing Output¶

The standard input and output channels for the process started by
call() are bound to the parent’s input and output. That means
the calling programm cannot capture the output of the command. Use
check_output() to capture the output for later processing.

import subprocess

output = subprocess.check_output(['ls', '-1'])
print 'Have %d bytes in output' % len(output)
print output

                                  

The ls -1 command runs successfully, so the text it prints to
standard output is captured and returned.

$ python subprocess_check_output.py

Have 462 bytes in output
__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py

This script runs a series of commands in a subshell. Messages are
sent to standard output and standard error before the commands exit
with an error code.

import subprocess

output = subprocess.check_output(
    'echo to stdout; echo to stderr 1>&2; exit 1',
    shell=True,
    )
print 'Have %d bytes in output' % len(output)
print output

                                  

The message to standard error is printed to the console, but the
message to standard output is hidden.

$ python subprocess_check_output_error.py

to stderr
Traceback (most recent call last):
  File "subprocess_check_output_error.py", line 14, in <module>
    shell=True,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.
7/subprocess.py", line 544, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'echo to stdout; echo to stderr
 1>&2; exit 1' returned non-zero exit status 1

To prevent error messages from commands run through
check_output() from being written to the console, set the
stderr parameter to the constant STDOUT.

import subprocess

output = subprocess.check_output(
    'echo to stdout; echo to stderr 1>&2; exit 1',
    shell=True,
    stderr=subprocess.STDOUT,
    )
print 'Have %d bytes in output' % len(output)
print output

                                  

Now the error and standard output channels are merged together so if
the command prints error messages, they are captured and not sent to
the console.

$ python subprocess_check_output_error_trap_output.py

Traceback (most recent call last):
  File "subprocess_check_output_error_trap_output.py", line 15, in <mo
dule>
    stderr=subprocess.STDOUT,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.
7/subprocess.py", line 544, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'echo to stdout; echo to stderr
 1>&2; exit 1' returned non-zero exit status 1

Working with Pipes Directly¶

By passing different arguments for stdin, stdout, and stderr it
is possible to mimic the variations of os.popen().

popen¶

To run a process and read all of its output, set the stdout value to
PIPE and call communicate().

import subprocess

print 'nread:'
proc = subprocess.Popen(['echo', '"to stdout"'], 
                        stdout=subprocess.PIPE,
                        )
stdout_value = proc.communicate()[0]
print 'tstdout:', repr(stdout_value)

This is similar to the way popen() works, except that the
reading is managed internally by the Popen instance.

$ python subprocess_popen_read.py


read:
        stdout: '"to stdout"n'

To set up a pipe to allow the calling program to write data to it, set
stdin to PIPE.

import subprocess

print 'nwrite:'
proc = subprocess.Popen(['cat', '-'],
                        stdin=subprocess.PIPE,
                        )
proc.communicate('tstdin: to stdinn')

To send data to the standard input channel of the process one time,
pass the data to communicate(). This is similar to using
popen() with mode ‘w’.

$ python -u subprocess_popen_write.py


write:
        stdin: to stdin

popen2¶

To set up the Popen instance for reading and writing, use a
combination of the previous techniques.

import subprocess

print 'npopen2:'

proc = subprocess.Popen(['cat', '-'],
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        )
stdout_value = proc.communicate('through stdin to stdout')[0]
print 'tpass through:', repr(stdout_value)

This sets up the pipe to mimic popen2().

$ python -u subprocess_popen2.py


popen2:
        pass through: 'through stdin to stdout'

popen3¶

It is also possible watch both of the streams for stdout and stderr,
as with popen3().

import subprocess

print 'npopen3:'
proc = subprocess.Popen('cat -; echo "to stderr" 1>&2',
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        )
stdout_value, stderr_value = proc.communicate('through stdin to stdout')
print 'tpass through:', repr(stdout_value)
print 'tstderr      :', repr(stderr_value)

Reading from stderr works the same as with stdout. Passing
PIPE tells Popen to attach to the channel, and
communicate() reads all of the data from it before returning.

$ python -u subprocess_popen3.py


popen3:
        pass through: 'through stdin to stdout'
        stderr      : 'to stderrn'

popen4¶

To direct the error output from the process to its standard output
channel, use STDOUT for stderr instead of PIPE.

import subprocess

print 'npopen4:'
proc = subprocess.Popen('cat -; echo "to stderr" 1>&2',
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
                        )
stdout_value, stderr_value = proc.communicate('through stdin to stdoutn')
print 'tcombined output:', repr(stdout_value)
print 'tstderr value   :', repr(stderr_value)

Combining the output in this way is similar to how popen4()
works.

$ python -u subprocess_popen4.py


popen4:
        combined output: 'through stdin to stdoutnto stderrn'
        stderr value   : None

Connecting Segments of a Pipe¶

Multiple commands can be connected into a pipeline, similar to the
way the Unix shell works, by creating separate Popen
instances and chaining their inputs and outputs together. The
stdout attribute of one Popen instance is used as the
stdin argument for the next in the pipeline, instead of the constant
PIPE. The output is read from the stdout handle for
the final command in the pipeline.

import subprocess

cat = subprocess.Popen(['cat', 'index.rst'], 
                        stdout=subprocess.PIPE,
                        )

grep = subprocess.Popen(['grep', '.. include::'],
                        stdin=cat.stdout,
                        stdout=subprocess.PIPE,
                        )

cut = subprocess.Popen(['cut', '-f', '3', '-d:'],
                        stdin=grep.stdout,
                        stdout=subprocess.PIPE,
                        )

end_of_pipe = cut.stdout

print 'Included files:'
for line in end_of_pipe:
    print 't', line.strip()

This example reproduces the command line cat index.rst | grep
«.. include» | cut -f 3 -d:, which reads the reStructuredText source
file for this section and finds all of the lines that include other
files, then prints only the filenames.

$ python -u subprocess_pipes.py

Included files:
        subprocess_os_system.py
        subprocess_shell_variables.py
        subprocess_check_call.py
        subprocess_check_output.py
        subprocess_check_output_error.py
        subprocess_check_output_error_trap_output.py
        subprocess_popen_read.py
        subprocess_popen_write.py
        subprocess_popen2.py
        subprocess_popen3.py
        subprocess_popen4.py
        subprocess_pipes.py
        repeater.py
        interaction.py
        signal_child.py
        signal_parent.py
        subprocess_signal_parent_shell.py
        subprocess_signal_setsid.py

Interacting with Another Command¶

All of the above examples assume a limited amount of interaction. The
communicate() method reads all of the output and waits for
child process to exit before returning. It is also possible to write
to and read from the individual pipe handles used by the
Popen instance. A simple echo program that reads from
standard input and writes to standard output illustrates this:

import sys

sys.stderr.write('repeater.py: startingn')
sys.stderr.flush()

while True:
    next_line = sys.stdin.readline()
    if not next_line:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

sys.stderr.write('repeater.py: exitingn')
sys.stderr.flush()

The script, repeater.py, writes to stderr when it starts and
stops. That information can be used to show the lifetime of the child
process.

The next interaction example uses the stdin and stdout file handles
owned by the Popen instance in different ways. In the first
example, a sequence of 10 numbers are written to stdin of the process,
and after each write the next line of output is read back. In the
second example, the same 10 numbers are written but the output is read
all at once using communicate().

import subprocess

print 'One line at a time:'
proc = subprocess.Popen('python repeater.py', 
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        )
for i in range(10):
    proc.stdin.write('%dn' % i)
    output = proc.stdout.readline()
    print output.rstrip()
remainder = proc.communicate()[0]
print remainder

print
print 'All output at once:'
proc = subprocess.Popen('python repeater.py', 
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        )
for i in range(10):
    proc.stdin.write('%dn' % i)

output = proc.communicate()[0]
print output

The «repeater.py: exiting» lines come at different points in the
output for each loop style.

$ python -u interaction.py

One line at a time:
repeater.py: starting
0
1
2
3
4
5
6
7
8
9
repeater.py: exiting


All output at once:
repeater.py: starting
repeater.py: exiting
0
1
2
3
4
5
6
7
8
9

Signaling Between Processes¶

The os examples include a demonstration of signaling
between processes using os.fork() and os.kill()
. Since each Popen instance
provides a pid attribute with the process id of the child process,
it is possible to do something similar with subprocess. For
example, using this script for the child process to be executed by the
parent process

import os
import signal
import time
import sys

pid = os.getpid()
received = False

def signal_usr1(signum, frame):
    "Callback invoked when a signal is received"
    global received
    received = True
    print 'CHILD %6s: Received USR1' % pid
    sys.stdout.flush()

print 'CHILD %6s: Setting up signal handler' % pid
sys.stdout.flush()
signal.signal(signal.SIGUSR1, signal_usr1)
print 'CHILD %6s: Pausing to wait for signal' % pid
sys.stdout.flush()
time.sleep(3)

if not received:
    print 'CHILD %6s: Never received signal' % pid

combined with this parent process

import os
import signal
import subprocess
import time
import sys

proc = subprocess.Popen(['python', 'signal_child.py'])
print 'PARENT      : Pausing before sending signal...'
sys.stdout.flush()
time.sleep(1)
print 'PARENT      : Signaling child'
sys.stdout.flush()
os.kill(proc.pid, signal.SIGUSR1)

the output is:

$ python signal_parent.py

PARENT      : Pausing before sending signal...
CHILD  14756: Setting up signal handler
CHILD  14756: Pausing to wait for signal
PARENT      : Signaling child
CHILD  14756: Received USR1

Process Groups / Sessions¶

Because of the way the process tree works under Unix, if the process
created by Popen spawns sub-processes, those children will not
receive any signals sent to the parent. That means, for example, it
will be difficult to cause them to terminate by sending
SIGINT or SIGTERM.

import os
import signal
import subprocess
import tempfile
import time
import sys

script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python signal_child.py
'''
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush()

proc = subprocess.Popen(['sh', script_file.name], close_fds=True)
print 'PARENT      : Pausing before sending signal to child %s...' % proc.pid
sys.stdout.flush()
time.sleep(1)
print 'PARENT      : Signaling child %s' % proc.pid
sys.stdout.flush()
os.kill(proc.pid, signal.SIGUSR1)
time.sleep(3)

The pid used to send the signal does not match the pid of the child of
the shell script waiting for the signal because in this example, there
are three separate processes interacting:

  1. subprocess_signal_parent_shell.py
  2. The Unix shell process running the script created by the main python
    program.
  3. signal_child.py
$ python subprocess_signal_parent_shell.py

PARENT      : Pausing before sending signal to child 14759...
Shell script in process 14759
+ python signal_child.py
CHILD  14760: Setting up signal handler
CHILD  14760: Pausing to wait for signal
PARENT      : Signaling child 14759
CHILD  14760: Never received signal

The solution to this problem is to use a process group to associate
the children so they can be signaled together. The process group is
created with os.setsid(), setting the “session id” to the
process id of the current process. All child processes inherit the
session id, and since it should only be set set in the shell created
by Popen and its descendants, os.setsid() should not be
called in the parent process. Instead, the function is passed to
Popen as the preexec_fn argument so it is run after the
fork() inside the new process, before it uses exec() to
run the shell.

import os
import signal
import subprocess
import tempfile
import time
import sys

script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python signal_child.py
'''
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush()

proc = subprocess.Popen(['sh', script_file.name], 
                        close_fds=True,
                        preexec_fn=os.setsid,
                        )
print 'PARENT      : Pausing before sending signal to child %s...' % proc.pid
sys.stdout.flush()
time.sleep(1)
print 'PARENT      : Signaling process group %s' % proc.pid
sys.stdout.flush()
os.killpg(proc.pid, signal.SIGUSR1)
time.sleep(3)

The sequence of events is:

  1. The parent program instantiates Popen.
  2. The Popen instance forks a new process.
  3. The new process runs os.setsid().
  4. The new process runs exec() to start the shell.
  5. The shell runs the shell script.
  6. The shell script forks again and that process execs Python.
  7. Python runs signal_child.py.
  8. The parent program signals the process group using the pid of the shell.
  9. The shell and Python processes receive the signal. The shell
    ignores it. Python invokes the signal handler.

To signal the entire process group, use os.killpg() with the pid
value from the Popen instance.

$ python subprocess_signal_setsid.py

PARENT      : Pausing before sending signal to child 14763...
Shell script in process 14763
+ python signal_child.py
CHILD  14764: Setting up signal handler
CHILD  14764: Pausing to wait for signal
PARENT      : Signaling process group 14763
CHILD  14764: Received USR1

See also

subprocess
Standard library documentation for this module.
os
Although many are deprecated, the functions for working with processes
found in the os module are still widely used in existing code.
UNIX SIgnals and Process Groups
A good description of UNIX signaling and how process groups work.
Advanced Programming in the UNIX(R) Environment
Covers working with multiple processes, such as handling signals, closing duplicated
file descriptors, etc.
pipes
Unix shell command pipeline templates in the standard library.

Exceptions raised in the child process, before the new program has started to execute, will be re-raised in the parent.

The most common exception raised is OSError. This occurs, for example, when trying to execute a non-existent file. Applications should prepare for OSError exceptions. Note that, when shell=True, OSError will be raised by the child only if the selected shell itself was not found. To determine if the shell failed to find the requested application, it is necessary to check the return code or output from the subprocess.

A ValueError will be raised if Popen is called with invalid arguments.

check_call() and check_output() will raise CalledProcessError if the called process returns a non-zero return code.

All of the functions and methods that accept a timeout parameter, such as call() and Popen.communicate() will raise TimeoutExpired if the timeout expires before the process exits.

Exceptions defined in this module all inherit from SubprocessError.

New in version 3.3: The SubprocessError base class was added.

Security Considerations

Unlike some other popen functions, this implementation will never implicitly call a system shell. This means that all characters, including shell metacharacters, can safely be passed to child processes. If the shell is invoked explicitly, via shell=True, it is the application’s responsibility to ensure that all whitespace and metacharacters are quoted appropriately to avoid shell injection vulnerabilities. On some platforms, it is possible to use shlex.quote() for this escaping.

Popen Objects

Instances of the Popen class have the following methods:

Popen.poll()

Check if child process has terminated. Set and return returncode attribute. Otherwise, returns None.

Popen.wait(timeout=None)

Wait for child process to terminate. Set and return returncode attribute.

If the process does not terminate after timeout seconds, raise a TimeoutExpired exception. It is safe to catch this exception and retry the wait.

Note

This will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that.

Changed in version 3.3: timeout was added.

Popen.communicate(input=None, timeout=None)

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate and set the returncode attribute. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to the child. If streams were opened in text mode, input must be a string. Otherwise, it must be bytes.

communicate() returns a tuple (stdout_data, stderr_data). The data will be strings if streams were opened in text mode; otherwise, bytes.

Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other than None in the result tuple, you need to give stdout=PIPE and/or stderr=PIPE too.

If the process does not terminate after timeout seconds, a TimeoutExpired exception will be raised. Catching this exception and retrying communication will not lose any output.

The child process is not killed if the timeout expires, so in order to cleanup properly a well-behaved application should kill the child process and finish communication:

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

Note

The data read is buffered in memory, so do not use this method if the data size is large or unlimited.

Changed in version 3.3: timeout was added.

Popen.send_signal(signal)

Sends the signal signal to the child.

Do nothing if the process completed.

Note

On Windows, SIGTERM is an alias for terminate(). CTRL_C_EVENT and CTRL_BREAK_EVENT can be sent to processes started with a creationflags parameter which includes CREATE_NEW_PROCESS_GROUP.

Popen.terminate()

Stop the child. On POSIX OSs the method sends SIGTERM to the child. On Windows the Win32 API function TerminateProcess() is called to stop the child.

Popen.kill()

Kills the child. On POSIX OSs the function sends SIGKILL to the child. On Windows kill() is an alias for terminate().

The following attributes are also available:

Popen.args

The args argument as it was passed to Popen – a sequence of program arguments or else a single string.

New in version 3.3.

Popen.stdin

If the stdin argument was PIPE, this attribute is a writeable stream object as returned by open(). If the encoding or errors arguments were specified or the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stdin argument was not PIPE, this attribute is None.

Popen.stdout

If the stdout argument was PIPE, this attribute is a readable stream object as returned by open(). Reading from the stream provides output from the child process. If the encoding or errors arguments were specified or the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stdout argument was not PIPE, this attribute is None.

Popen.stderr

If the stderr argument was PIPE, this attribute is a readable stream object as returned by open(). Reading from the stream provides error output from the child process. If the encoding or errors arguments were specified or the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stderr argument was not PIPE, this attribute is None.

Popen.pid

The process ID of the child process.

Note that if you set the shell argument to True, this is the process ID of the spawned shell.

Popen.returncode

The child return code, set by poll() and wait() (and indirectly by communicate()). A None value indicates that the process hasn’t terminated yet.

A negative value -N indicates that the child was terminated by signal N (POSIX only).

Windows Popen Helpers

The STARTUPINFO class and following constants are only available on Windows.

class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)

Partial support of the Windows STARTUPINFO structure is used for Popen creation. The following attributes can be set by passing them as keyword-only arguments.

Changed in version 3.7: Keyword-only argument support was added.

dwFlags

A bit field that determines whether certain STARTUPINFO attributes are used when the process creates a window.

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

If dwFlags specifies STARTF_USESTDHANDLES, this attribute is the standard input handle for the process. If STARTF_USESTDHANDLES is not specified, the default for standard input is the keyboard buffer.

hStdOutput

If dwFlags specifies STARTF_USESTDHANDLES, this attribute is the standard output handle for the process. Otherwise, this attribute is ignored and the default for standard output is the console window’s buffer.

hStdError

If dwFlags specifies STARTF_USESTDHANDLES, this attribute is the standard error handle for the process. Otherwise, this attribute is ignored and the default for standard error is the console window’s buffer.

wShowWindow

If dwFlags specifies STARTF_USESHOWWINDOW, this attribute can be any of the values that can be specified in the nCmdShow parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this attribute is ignored.

SW_HIDE is provided for this attribute. It is used when Popen is called with shell=True.

lpAttributeList

A dictionary of additional attributes for process creation as given in STARTUPINFOEX, see UpdateProcThreadAttribute.

Supported attributes:

handle_list

Sequence of handles that will be inherited. close_fds must be true if non-empty.

The handles must be temporarily made inheritable by os.set_handle_inheritable() when passed to the Popen constructor, else OSError will be raised with Windows error ERROR_INVALID_PARAMETER (87).

Warning

In a multithreaded process, use caution to avoid leaking handles that are marked inheritable when combining this feature with concurrent calls to other process creation functions that inherit all handles such as os.system(). This also applies to standard handle redirection, which temporarily creates inheritable handles.

New in version 3.7.

Windows Constants

The subprocess module exposes the following constants.

subprocess.STD_INPUT_HANDLE

The standard input device. Initially, this is the console input buffer, CONIN$.

subprocess.STD_OUTPUT_HANDLE

The standard output device. Initially, this is the active console screen buffer, CONOUT$.

subprocess.STD_ERROR_HANDLE

The standard error device. Initially, this is the active console screen buffer, CONOUT$.

subprocess.SW_HIDE

Hides the window. Another window will be activated.

subprocess.STARTF_USESTDHANDLES

Specifies that the STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput, and STARTUPINFO.hStdError attributes contain additional information.

subprocess.STARTF_USESHOWWINDOW

Specifies that the STARTUPINFO.wShowWindow attribute contains additional information.

subprocess.CREATE_NEW_CONSOLE

The new process has a new console, instead of inheriting its parent’s console (the default).

subprocess.CREATE_NEW_PROCESS_GROUP

A Popencreationflags parameter to specify that a new process group will be created. This flag is necessary for using os.kill() on the subprocess.

This flag is ignored if CREATE_NEW_CONSOLE is specified.

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have an above average priority.

New in version 3.7.

subprocess.BELOW_NORMAL_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have a below average priority.

New in version 3.7.

subprocess.HIGH_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have a high priority.

New in version 3.7.

subprocess.IDLE_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have an idle (lowest) priority.

New in version 3.7.

subprocess.NORMAL_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have an normal priority. (default)

New in version 3.7.

subprocess.REALTIME_PRIORITY_CLASS

A Popencreationflags parameter to specify that a new process will have realtime priority. You should almost never use REALTIME_PRIORITY_CLASS, because this interrupts system threads that manage mouse input, keyboard input, and background disk flushing. This class can be appropriate for applications that “talk” directly to hardware or that perform brief tasks that should have limited interruptions.

New in version 3.7.

subprocess.CREATE_NO_WINDOW

A Popencreationflags parameter to specify that a new process will not create a window.

New in version 3.7.

subprocess.DETACHED_PROCESS

A Popencreationflags parameter to specify that a new process will not inherit its parent’s console. This value cannot be used with CREATE_NEW_CONSOLE.

New in version 3.7.

subprocess.CREATE_DEFAULT_ERROR_MODE

A Popencreationflags parameter to specify that a new process does not inherit the error mode of the calling process. Instead, the new process gets the default error mode. This feature is particularly useful for multithreaded shell applications that run with hard errors disabled.

New in version 3.7.

subprocess.CREATE_BREAKAWAY_FROM_JOB

A Popencreationflags parameter to specify that a new process is not associated with the job.

New in version 3.7.


© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/subprocess.html


Python

3.11

  • subprocess — Subprocess management

    Source code: Lib/subprocess.py The subprocess module allows you to spawn new processes, connect their input/output/error pipes, and obtain return codes.

  • Popen Constructor

    The underlying process creation and management this module handled by Popen class.

  • Older high-level API

    Prior to Python 3.5, these three functions comprised high level API subprocess.

  • symtable — Access to the compiler’s symbol tables

    Source code: Lib/symtable.py Symbol tables are generated by the compiler from AST just before bytecode is Return the toplevel SymbolTable for Python source

I am a beginner at python coding.

I wrote a simple code that lists a number of programs and asks the user to choose one of the programs. It will then open a website with the version history of that program, and, where it exists, run the updater of the program.

Initially I wrote the program manually writing out the list of programs (20) and then manually write out the url and, where relevant, the path and file name to the updater. Something like:

if choice == 1
   url = 'https://blablabla'
   prg = 'C:\Program Files\blablabla'

After manually defining the URL and prg variables for all 20 options, I run:

webbrowser.open_new_tab(url)
subprocess.Popen(prg)

This works fine.

Then I tried to write the code where the list of programs and the url and file paths are listed in a .csv file. The values for the url and prg variables are read from the .csv file (using numpy load.txt)

webbrowser.open_new_tab(url)

works fine

However:

subprocess.Popen(prg)

gives an error message if the file path has a blank space in it (which is in 19 out of the 20 options). The error message is:

Error:

Traceback (most recent call last): File "test.py", line 32, in <module> mainmenu() File "test.py", line 30, in mainmenu subprocess.Popen(prg) File "C:UserszorinAppDataLocalProgramsPythonPython38libsubprocess.py", line 858, in _init__ self._execute_child(args, executable, preexec_fn, close_fds, File "C:UserszorinAppDataLocalProgramsPythonPython38libsubprocess.py", line 1311, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args, FileNotFoundError: [WinError 2] The system cannot find the file specified

One example:

In the original (long-winded)code I manually set the full file name for Chrome:

prg = 'C:\Program Files\Google\Chrome\Application\chrome.exe'

and

subprocess.Popen(prg)

runs Chrome without a problem.

In the updated code the same full file name is read into prg, but this time

subprocess.Popen(prg)

gives the above-mentioned error code (if the file path has a black space it).

In the new code

print(prg)

will give:

Output:

C:\Program Files\Google\Chrome\Application\chrome.exe

so the correct value is read into the variable.

Any suggestions what I am doing wrong?

I use Windows

Posts: 3,889

Threads: 56

Joined: Jan 2018

Reputation:
307

Try subprocess.Popen([prg]) perhaps.

Posts: 567

Threads: 1

Joined: Aug 2019

Reputation:
55

May-04-2021, 08:28 AM
(This post was last modified: May-04-2021, 08:28 AM by ibreeden.)

(May-03-2021, 07:51 PM)herwin Wrote: In the new code

print(prg)

will give:

Output:

C:\Program Files\Google\Chrome\Application\chrome.exe

so the correct value is read into the variable.

No it is not correct. The path should be: «C:Program FilesGoogleChromeApplicationchrome.exe», so without the double backlashes.
The backslash has a special meaning in Python. So to assign a string literal with backslashes you have to double the backslash to make clear you really mean one backslash.

>>> prg = 'C:\Program Files\Google\Chrome\Application\chrome.exe'
>>> print(prg)
C:Program FilesGoogleChromeApplicationchrome.exe

So «prg» will contain only single backslashes.
Nowadays a more popular way to assign such a variable is to assign a raw string by putting an «r» before the string literal.

>>> prg = r'C:Program FilesGoogleChromeApplicationchrome.exe'
>>> print(prg)
C:Program FilesGoogleChromeApplicationchrome.exe

So make sure you get rid of the double backslashes.

Posts: 6,575

Threads: 116

Joined: Sep 2016

Reputation:
487

May-04-2021, 09:54 AM
(This post was last modified: May-04-2021, 09:55 AM by snippsat.)

(May-03-2021, 07:51 PM)herwin Wrote: gives the above-mentioned error code (if the file path has a black space it).

In the new code

print(prg)

Do print(repr(prg)) then you see if there is a space.
It’s normal when read from file eg csv to use strip() so there no space at beginning or end.

>>> path = r'C:codefile.csv '
# Looks ok,but are not
>>> print(path)
C:codefile.csv 
>>> 
>>> # To see all
>>> print(repr(path))
'C:\code\file.csv '
>>> 
>>> # Fix
>>> path.strip()
'C:\code\file.csv'

herwin

Programmer named Tim


Posts: 7

Threads: 1

Joined: May 2021

Reputation:
0

(May-03-2021, 09:15 PM)Gribouillis Wrote: Try subprocess.Popen([prg]) perhaps.

Thank you for your answer.

Unfortunately the problem remains the same

herwin

Programmer named Tim


Posts: 7

Threads: 1

Joined: May 2021

Reputation:
0

(May-04-2021, 08:28 AM)ibreeden Wrote:

(May-03-2021, 07:51 PM)herwin Wrote: In the new code

print(prg)

will give:

Output:

C:\Program Files\Google\Chrome\Application\chrome.exe

so the correct value is read into the variable.

No it is not correct. The path should be: «C:Program FilesGoogleChromeApplicationchrome.exe», so without the double backlashes.
The backslash has a special meaning in Python. So to assign a string literal with backslashes you have to double the backslash to make clear you really mean one backslash.

>>> prg = 'C:\Program Files\Google\Chrome\Application\chrome.exe'
>>> print(prg)
C:Program FilesGoogleChromeApplicationchrome.exe

So «prg» will contain only single backslashes.
Nowadays a more popular way to assign such a variable is to assign a raw string by putting an «r» before the string literal.

>>> prg = r'C:Program FilesGoogleChromeApplicationchrome.exe'
>>> print(prg)
C:Program FilesGoogleChromeApplicationchrome.exe

So make sure you get rid of the double backslashes.

Thank you for your response and suggestions.

I have tried with the single and double backslashes in the csv file. The error message stays the same in both cases.

How do I read the values from the csv file into the prg variable as a raw string?

herwin

Programmer named Tim


Posts: 7

Threads: 1

Joined: May 2021

Reputation:
0

(May-04-2021, 09:54 AM)snippsat Wrote:

(May-03-2021, 07:51 PM)herwin Wrote: gives the above-mentioned error code (if the file path has a blank space it).

In the new code

print(prg)

Do print(repr(prg)) then you see if there is a space.
It’s normal when read from file eg csv to use strip() so there no space at beginning or end.

>>> path = r'C:codefile.csv '
# Looks ok,but are not
>>> print(path)
C:codefile.csv 
>>> 
>>> # To see all
>>> print(repr(path))
'C:\code\file.csv '
>>> 
>>> # Fix
>>> path.strip()
'C:\code\file.csv'

Thanks.

I check as per your suggestion and there are no spaces at the beginning or the end of the string.
The problem appears to be the blank space in the middle of the string (between ‘program’ and ‘files’ in the file path)

Posts: 3,889

Threads: 56

Joined: Jan 2018

Reputation:
307

Have you tried Popen([prg]) instead of Popen(prg) ? The less ambiguous way to call Popen() is to pass a list of the arguments.

herwin

Programmer named Tim


Posts: 7

Threads: 1

Joined: May 2021

Reputation:
0

(May-04-2021, 03:42 PM)Gribouillis Wrote: Have you tried Popen([prg]) instead of Popen(prg) ? The less ambiguous way to call Popen() is to pass a list of the arguments.

Thanks.
Yes, I did. Unfortunately that does not seem to solve the problem (I get the same error message)

Posts: 6,575

Threads: 116

Joined: Sep 2016

Reputation:
487

May-04-2021, 10:56 PM
(This post was last modified: May-04-2021, 10:56 PM by snippsat.)

(May-04-2021, 03:30 PM)herwin Wrote: The problem appears to be the blank space in the middle of the string (between ‘program’ and ‘files’ in the file path)

Should not be a problem,a quick test.
So this run fine no error,and open programs.

import subprocess

core = r'C:Program FilesCore TempCore Temp.exe'
prg = r'C:Program Files (x86)GoogleChromeApplicationchrome.exe'
print(repr(core))
print(repr(prg))
subprocess.Popen([core])
subprocess.Popen([prg])

Output:

E:div_codenew λ python p_open.py 'C:\Program Files\Core Temp\Core Temp.exe' 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'

If put paths is a file,run fine.

Output:

# prog.csv C:Program FilesCore TempCore Temp.exe,C:Program Files (x86)GoogleChromeApplicationchrome.exe
import subprocess
import csv

with open('prog.csv') as f:
    reader = csv.reader(f, delimiter=',')
    prog_lst = list(reader)

for prog in prog_lst[0]:
    subprocess.Popen([prog])

so prog_lst looks like this,se that there are two \ when read from a file,
then there is no need for r(raw string) as if write/copy path yourself.

>>> prog_lst
[['C:\Program Files\Core Temp\Core Temp.exe',
  'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe']]

Понравилась статья? Поделить с друзьями:
  • Pooler error unexpected response from login query
  • Primary name server not listed at parent как исправить
  • Poweramp как изменить теги
  • Postgresql error missing from clause entry for table
  • Polaris puh 8060 tfd ошибка ef