I want to grep a Linux Screen ID in Python to check if this Screen exists. I would like to convert my os.system
command to subprocess
command.
From this:
os.system('screen -ls | grep -i ' INSTANCE_NAME ' >/dev/null')
to this:
subprocess.check_call(['screen', '-ls', '|', 'grep', '-i', INSTANCE_NAME])
The os.system
command works fine, but not the subprocess
command. And what are the differences between subprocess.run
, subprocess.call
and subprocess.check_call
? Can someone help me out?
I'm using Python 3.10 on Linux Ubuntu Server 20.04 LTS
CodePudding user response:
The pipe |
is a shell command that connects the output of a process to the input of another. If you want to use it in subprocess
, you have to tell the subprocess
function that you want to run the command in a shell like this:
subprocess.check_call('screen -ls | grep -i ' INSTANCE_NAME, shell=True)
If you use this, you should take into account the security considerations of the shell invocation. If you want to achieve the same thing without a shell, you must use two subprocesses. Here is an example:
p1 = subprocess.Popen(["screen", "-ls"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(
["grep", "-i", INSTANCE_NAME], stdin=p1.stdout, stdout=subprocess.PIPE
)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0].decode()
(See https://docs.python.org/3/library/subprocess.html#replacing-shell-pipeline)
And what are the differences between subprocess.run, subprocess.call and subprocess.check_call? Can someone help me out?
The documentation provides extensive information about the difference between these functions. The TL;DR is:
call
andcheck_call
are part of the old high-level API whilerun
is the new recommended approach to invoke subprocesses.call
: runs a command and returns its return codecheck_call
: like call but raises an exception if the return code is not 0run
: well, you have access to the return code, the output, you can raise for non-zero codes, etc, etc. The documentation has all the information.