Print Failure or success based on the value of the standalone tool

Cameron Simpson cs at cskk.id.au
Thu May 10 23:38:36 EDT 2018


On 11May2018 06:53, Ganesh Pal <ganesh1pal at gmail.com> wrote:
>On Thu, May 10, 2018, 22:31 Rob Gaddi
>> By not using os.system, it's been superseded for reasons exactly like
>> yours.  https://docs.python.org/3/library/subprocess.html is your friend.
>
>Can someone please help me understand this better for me with a program .
>Will the  returncode of subprocess still not be  0 or -ve number ?
>
>My requirement is let the  test_standalone_tool.py script which is a
>wrapper around standalone_tool.py print pass /fail based on the possible
>values I.e True , False and None
>
>I'm not sure weather if I need to i.e replace os.system with subprocess or
>make changes in standalone_tool.py to return 0 or -1( use sys.exit())

Your problem is with standalone_tool.py. os.system() returns the exit status of 
the shell which ran your command, and that is in turn the exit status of the 
last command the shell ran i.e. your command.

Your problem is that standalone_tool.py does not return a relevant exit status.  
As far as Python is concerned your script ran to completion and Python returns 
an exit status of 0 unless you arrange otherwise.

Consider this small script:

  #!/usr/bin/python

  import sys

  def func():
    return 1

  if func() == 1:
    # indicate success as an exit status
    sys.exit(0)
  else:
    # indicate failure as an exit status
    sys.exit(1)

Your script doesn't call sys.exit(), and as such, unless it outright aborts 
(for example, from an exception) Python itself returns a 0 exit status.  
Therefore your standalone_tool.py always has an exit status of 0. Make a 
suitable call to sys.exit() at the end to return a meaningful exit status.

Returning to system() versus the subprocess module, there are other reasons to 
prefer the subprocess module. The biggest is that os.system() runs a shell 
command, a string passed to the programme /bin/sh. As such, that string is 
subject to all manner of syntax - anything the shell can understand.

For example, if you wanted to pass a filename as an argument to your script you 
would need to ensure that nothing in the filename could be misinterpreted as 
punctuation. For example, a filename containing spaces would be handled as 2 
distinct arguments by the shell unless you quote the name.

Using the subprocess module you can pass such items directly to your script 
instead of going _through_ the shell as an intermediate command. Compare:

  import os
  import subprocess

  os.system('standalone_tool.py my-filename-here')
  subprocess.run(['standalone_tool.py', 'my-filename-here'])

The former invokes the shell (/bin/sh) with the string 'standalone_tool.py 
my-filename-here', which the shell interprets. The latter directly runs your 
script.

Cheers,
Cameron Simpson <cs at cskk.id.au>



More information about the Python-list mailing list