Package: simpleshell
Simple ShellRun a shell command, and receivestdout,stderr, andreturncode.  It's dead simple.$python3[...]>>>fromsimpleshellimportss>>>output=ss('head -3 LICEN*')MITLicensePermissionisherebygranted,freeofcharge,toanypersonobtainingacopy>>>print(output)CompletedProcess(args='head LICEN*',returncode=0,stdout=['MIT License','','Permission is hereby granted, free of charge, to any person obtaining a copy'],stderr=[''])>>>All calls are synchronous, therefore it's not possible to see the output until the command exits. This makes Simple Shell unsuitable fortailing a log.Install$ python3 -m pip install simpleshellUsefromsimpleshellimportssoutput=ss('ls -la')# Prints the result on the screen through stdoutpprint(vars(output))# Prints the dict below{'args':'ls -la','returncode':0,'stderr':[''],'stdout':['total 28','drwxr-xr-x 13 calvin staff  416 Oct 23 00:08 .','drwxr-xr-x  7 calvin staff  224 Oct 22 16:56 ..','drwxr-xr-x 13 calvin staff  416 Oct 22 23:51 .git','-rw-r--r--  1 calvin staff   63 Oct 22 21:28 .gitignore','drwxr-xr-x  9 calvin staff  288 Oct 23 00:08 .idea','-rw-r--r--  1 calvin staff 1036 Oct 22 22:27 LICENSE','-rw-r--r--  1 calvin staff  287 Oct 22 23:24 Makefile','-rw-r--r--  1 calvin staff 4320 Oct 23 00:08 README.md','drwxr-xr-x  4 calvin staff  128 Oct 22 23:51 dist','-rw-r--r--  1 calvin staff  104 Oct 22 21:57 pyproject.toml','-rw-r--r--  1 calvin staff  594 Oct 22 23:50 setup.cfg','drwxr-xr-x  4 calvin staff  128 Oct 22 23:51 src','drwxr-xr-x  2 calvin staff   64 Oct 22 17:03 tests','']}Return valuesOn successCompletedProcessobject with member variablesargs,returncode,stdout,stderr.stdoutandstderrmay be astror alist[str]based on optional parameterconvert_stdout_stderr_to_list.On errorifoptionalparameter'exit_on_error':nothingelse:subprocess.CalledProcessErrorexceptionobjectOptional parametersprint_output_on_success=TrueWhenFalse, nothing gets printed when the command exits with0.>>>output=ss('head -3 LICEN*',print_output_on_success=False)>>>print_output_on_error=TrueWhenFalse, nothing gets printed when the command exists with a non-0.In the below example, the command exited with return code127and caused thepython3process to exit.>>>output=ss('invalid command',print_output_on_error=False)$echo$?127$convert_stdout_stderr_to_list=TrueWhenFalse,output.stdoutandoutput.stderrare strings with\nembedded in them.>>>output=ss('head -3 LICEN*',convert_stdout_stderr_to_list=False)MITLicensePermissionisherebygranted,freeofcharge,toanypersonobtainingacopy>>>print(output)CompletedProcess(args='head LICEN*',returncode=0,stdout='MIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n',stderr='')>>>keep_empty_lines=TrueWhenFalseandconvert_stdout_stderr_to_listisTrue, empty lines formoutput.stdoutandoutput.stderrlists are removed.In the below example, there is an empty line after the first lineMIT License, butoutput.stdoutlist doesn't contain the empty line.⚠️ This parameter does not change the way output is printed.>>>output=ss('head -3 LICEN*',keep_empty_lines=False)MITLicensePermissionisherebygranted,freeofcharge,toanypersonobtainingacopy>>>print(output)CompletedProcess(args='head LICEN*',returncode=0,stdout=['MIT License','Permission is hereby granted, free of charge, to any person obtaining a copy'],stderr=[])>>>exit_on_error=TrueWhenFalse, a command exiting with a non-0return code doesn't cause thepython3process to exit.
Afterward,subprocess.CalledProcessErrorexception object is returned so that the caller can further examine the error.This is useful for usinggrepto monitor for something to disappear.
In the below example,grepis waiting forprocess_waiting_to_finishprocess to complete and exit.>>>output=ss('ps | grep "[p]rocess_waiting_to_finish"',print_output_on_error=False,exit_on_error=False)>>>print(type(output))<class'subprocess.CalledProcessError'>>>>print(output.returncode)1Examining the output's return code is important. In the below example, we have specified an invalid flag-Ytogrep,
and as a resultgrepexited with2. This is different from the previous example which exited with1,
which signals that the error is about missing search results, as opposed to failing because of an invalid flag.>>>output=ss('ps | grep -Y "[p]rocess_waiting_to_finish"',print_output_on_error=False,exit_on_error=False)>>>print(output.returncode)2echo=FalseWhenTrue, the command is printed before the output is printed. This is useful for creating a screen capture which shows the command that was run.⚠️ The leading$does not change to#even if you'reroot. PR welcome.>>>output=ss('head -3 LICEN*',echo=True)$head-3LICEN*MITLicensePermissionisherebygranted,freeofcharge,toanypersonobtainingacopy>>>timeout=60Number of seconds to wait for the process to finish before exiting with an error. Since all calls are synchronous, it's not possible to see the output until the command exits.In the below example, the exception detail was printed becauseprint_output_on_errordefaults toTrue, and thepython3process exited becauseexit_on_erroralso defaults toTrue.>>>ss('sleep 10',timeout=3)Command'sleep 10'timedoutafter3seconds$