Home > database >  Return Values from Python Script to Bash Script is different when used with Print Statement
Return Values from Python Script to Bash Script is different when used with Print Statement

Time:07-28

I have a bash command that is as below:

    dependencies=$(/path/to/my-profiles.py --my-profiles pytest)
    IFS=' ' read -r -a arr <<<"$dependencies"
    declare -p arr

    for i in "${arr[@]}"
    do
        echo "$i"
    done

And my Python script is as below:

my-script.py
def main():
    parser = argparse.ArgumentParser(description='My script')
    parser.add_argument('--my-profiles', dest="profiles", 
                        type=str,
                        default='')
    parsed_args = parser.parse_args()
    dependencies = get_dependencies(args.profiles)
    return dependencies

def get_dependencies(profiles):
    return ' '.join([
       'mock-alchemy', 'pytest-mock', 'pytest-datafixtures', 'pytest-describe', 'pytest-unordered', 'requests-mock'
       ])

When I run the bash script with the above python script, I get the output as below:

mock-alchemy pytest-mock pytest-datafixtures pytest-describe pytest-unordered requests-mock
declare -a arr='()'

However, if I add print statement in my python script I get the result as I want:

my-script.py
def main():
    parser = argparse.ArgumentParser(description='My script')
    parser.add_argument('--tox-profiles', dest="profiles", 
                        type=str,
                        default='')
    parsed_args = parser.parse_args()
    dependencies = get_dependencies(args.profiles)
    print(dependencies)
    return dependencies

def get_dependencies(profiles):
    return ' '.join([
       'mock-alchemy', 'pytest-mock', 'pytest-datafixtures', 'pytest-describe', 'pytest-unordered', 'requests-mock'
       ])

With addition of print statement in the script, I get the below result:

mock-alchemy pytest-mock pytest-datafixtures pytest-describe pytest-unordered requests-mock
declare -a arr='([0]="mock-alchemy" [1]="pytest-mock" [2]="pytest-datafixtures" [3]="pytest-describe" [4]="pytest-unordered" [5]="requests-mock")'
mock-alchemy
pytest-mock
pytest-datafixtures
pytest-describe
pytest-unordered
requests-mock

I want my solution to as the second type, but I do not want to add a print statement. I want to know what am I doing wrong and how can I fix it?

CodePudding user response:

main can return a value, but that isn't exposed to the shell in any way. You cannot return arbitrary data from one process to another; you can only write to a file (using "file" in the loosest sense; could be a disk file, a socket, a pipe, etc.)

Writing the results to standard output and letting the shell capture that output, as you are doing, is the standard method for a child to communicate with its parent.

As such, the return statement is unnecessary.

def main():
    parser = argparse.ArgumentParser(description='My script')
    parser.add_argument('--tox-profiles', dest="profiles", 
                        type=str,
                        default='')
    parsed_args = parser.parse_args()
    dependencies = get_dependencies(args.profiles)
    print(dependencies)
  • Related