Home > OS >  subprocess.run()'s output is empty
subprocess.run()'s output is empty

Time:10-01

Below is the command:

    try:
        op = subprocess.run(['docker', 'login', '-u', 'username', '-p', 'password', 'dockerhub.com'], check=True, stdout=sys.stdout, stderr=subprocess.PIPE)
        print("Docker stdout :", op.stdout)
        print("Docker Error :", op.stderr.decode("utf-8"))
    except:
    traceback.print_exc()

It's working good, when the right password is provided and the 2 print statements are working as expected.

Login Succeeded
Docker stdout : None
Docker Error :

In case of incorrect password, I would like to capture the output as seen while running on the shell(bash), like below:

Error response from daemon: Get https://dockerhub.com/v2/: unknown: Bad credentials

instead I receive the traceback, where the above error message is not seen.

Traceback (most recent call last):
  File "/home/scripts/test.py", line 54, in my_func
    op = subprocess.run(['docker', 'login', '-u', 'username', '-p', 'incorrectpassword', 'dockerhub.com'], check=True, stdout=sys.stdout, stderr=subprocess.PIPE)
  File "/usr/local/lib/python3.5/subprocess.py", line 708, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['docker', 'login', '-u', 'username', '-p', 'incorrectpassword', 'dockerhub.com']' returned non-zero exit status 1
Traceback (most recent call last):

CodePudding user response:

You can also catch the subprocess.CalledProcessError Exception. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.

try:
    op = subprocess.run(['docker', 'login', '-u', 'username', '-p', 'password', 'dockerhub.com'], check=True, stdout=sys.stdout, stderr=subprocess.PIPE)
    print("Docker stdout :", op.stdout)
except subprocess.CalledProcessError as e:
    exit_code = e.returncode
    stderror = e.stderr
    print(exit_code, stderror)

CodePudding user response:

try this ( add capture_output=True )

try:
    op = subprocess.run(['docker', 'login', '-u', 'username', '-p', 'password', 'dockerhub.com'], check=True, stdout=sys.stdout, stderr=subprocess.PIPE,capture_output=True)
    print("Docker stdout :", op.stdout)
    print("Docker Error :", op.stderr.decode("utf-8"))
except:
traceback.print_exc()

CodePudding user response:

Two remarks:

1: You called subprocess.run() with check=True. This causes the exception that you observed.

See the documentation:

If check is true, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.

The simples solution is to use check=False (which is the default value, so you could just reove that argument). Then, after subprocess.run() has completed, check op.returncode and op.stderr.

Alternatively, you could use check=True and catch the exception, which was also mentioned in other answers.

2: You used stdout=sys.stdout, stderr=subprocess.PIPE.

This will print the standard output of the process to the standard output of the system (i.e., the console). If you want to capture the standard output, you should use stdout=subprocess.PIPE instead (or use capture_output=True, which is an alternative way to set the stdout and stderr arguments).

  • Related