Calling python script from bash script and getting it's return value


I’ve bash script doing some tasks but I need to manipulate on string obtained from configuration (for simplification in this test it’s hardcoded). This manipulation can be done easily in python but is not simple in bash, so I’ve written a script in python doing this tasks and returning a string (or ideally an array of strings).
I’m calling this python script in my bash script. Both scripts are in the same directory and this directory is added to environment variables. I’m testing it on Ubuntu 22.04.
My python script below:

def Get(input: str) -> list:
    #Doing tasks - arr is an output array
    return ' '.join(arr) #or ideally return arr

My bash script used to call the above python script

ARR=("$(python -c "from test import Get; Get('val1, val2,val3')")")
echo $ARR
for ELEMENT in "${ARR[@]}"; do
  echo "$ELEMENT"

When I added print in python script for test purposes I got proper results, so the python script works correctly. But in the bash script I got simply empty line. I’ve tried also something like that: ARR=("$(python -c "from test import Get; RES=Get('val1, val2,val3')")") and the iterate over res and got the same response.
It seems like the bash script cannot handle the data returned by python.
How can I rewrite this scripts to properly get python script response in bash?
Is it possible to get the whole array or only the string?

Asked By: Aenye_Cerbin



How can I rewrite this scripts to properly get python script response in bash?

Serialize the data from python side and deserialize on bash. Decide on proper protocol between the processes that would preserve any characters.

The best looks like it is to use newline or zero separated strings (protocol). Output delimiter separated elements from python (serialize) and read them properly on with readarray on bash side (deserialize).

$ tmp=$(python -c 'arr=[1,2,3]; print(*arr)')
$ readarray -t array <<<"$tmp"
$ declare -p array
declare -a array=([0]="1" [1]="2" [2]="3")

Or with zero separated stream. Note that Bash can’t store zero bytes in variables, so we use redirection with process subtitution:

$ readarray -d '' -t array < <(python -c 'arr=[1,2,3]; print(*arr, sep="", end="")')
$ declare -p array
declare -a array=([0]="1" [1]="2" [2]="3")
Answered By: KamilCuk

I’ve solved my problem by exporting a string with elements separated by space.
I’ve also rewritten python code not to be a function but a script.

import sys

if len(sys.argv) > 1:
   input = sys.argv[1]
   #Doing tasks - arr is an output array
   for element in arr:

ARRAY=$(python 'val1, val2,val3')
for ELEMENT in $ARRAY; do
    echo "$ELEMENT"
Answered By: Aenye_Cerbin
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.