skip to Main Content

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:

#!/usr/bin/python
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

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

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?

2

Answers


  1. Chosen as BEST ANSWER

    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:
          print(element)
    
    ARRAY=$(python script.py 'val1, val2,val3')
    for ELEMENT in $ARRAY; do
        echo "$ELEMENT"
    done
    

  2. 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")
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search