Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python unexpected non-zero returncode when checking alias command set in .bashrc file

I want to call an alias command set in a .bashrc file from python. However, the returncode of source ~/.bashrc; command -v command is for some reason 1 instead of 0 which is the case if the same command is executed directly in the shell. It should be noted that with a default command like echo instead of the alias command, python correclty returns 0 as the returncode.

To demonstrate the issue, I created a minimal example, where I use a regular shell script define_alias.sh instead of the .bashrc file:

test_bash_command.py:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import os
import subprocess

path_home = os.path.expanduser('~')
proc = subprocess.Popen(['/bin/bash', '-c', 'source %s/define_alias.sh; command -v testcommand' % path_home], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

proc_stdout, proc_stderr = proc.communicate()
proc_returncode = proc.returncode

print("Returncode: %s" % proc_returncode)
print("Stdout: %s" % proc_stdout)
print("Stderr: %s" % proc_stderr)

define_alias.sh:

# .bashrc
# imagine this is a .bashrc file

echo "I'm in the shell script"
alias testcommand='echo THIS IS A TEST'

Output:

wssadmin /global/wss/fs01/fk_bpr/waif_v8
$ python test_bash_command.py
Returncode: 1
Stdout: b"I'm in the shell script\n"
Stderr: b''

wssadmin /global/wss/fs01/fk_bpr/waif_v8
$ env -i bash --norc --noprofile
bash-4.4$ bash -c "source /home/wssadmin/define_alias.sh; command -v testcommand; echo $?"
I'm in the shell script
0
bash-4.4$ source /home/wssadmin/define_alias.sh; command -v testcommand; echo $?
I'm in the shell script
alias testcommand='echo THIS IS A TEST'
0
bash-4.4$ exit
exit

wssadmin /global/wss/fs01/fk_bpr/waif_v8
$ source /home/wssadmin/define_alias.sh; command -v testcommand; echo $?
I'm in the shell script
alias testcommand='echo THIS IS A TEST'
0

Question: Why is the returncode given to python not 0 like in the bash case? How can I get a returncode of 0 for the given command and additionally retrieve the stdout and stderr of the command -v testcommand (instead of only having that of the echo command)?

The source command itself is executed, which can be seen in the printed stdout variable. Please do note that I would not like to change the /bin/bash -c nor the shell=False parameter in subprocess.Popen as otherwise I would get issues with other commands called in other python scripts by a run_bash_cmd function wrapped around the subprocess.Popen.

Your help is much appreciated!

>Solution :

You need to run shopt -s expand_aliases to enable alias support, which is turned off by default in noninteractive shells. (Historically, aliases were part of the optional interactive extensions in the User Portability Utilities annex to the POSIX sh standard; it’s only as of the Issue 7 revision to the POSIX standard that they’re part of the proper base featureset).

>>> subprocess.run(['bash', '-c', 'alias foo=true;'
...                 'command -v foo']).returncode
1
>>> subprocess.run(['bash', '-c', 'alias foo=true;'
...                 'shopt -s expand_aliases; command -v foo']).returncode
alias foo='true'
0
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading