0

I have a Python script which, at any point in its execution, may print out text. I'm running that Python script from a Bash script - I want the Bash to be able to capture all of the output from the Python and store it in an array.

So say this is my Python:

print("foo")
print("bar baz")
print("")
print("moo")

(And there could well be code before and after each of these print statements.) I would want Bash to run the Python script, grab the output and pop it into an array like so:

var=('foo' 'bar' 'baz' '' 'moo')

Here's what I've tried:

#!/usr/bin/bash

var=($(python pyspace.py))
echo "${var[@]}" 
echo "${#var[@]}"
for i in "${!var[@]}"; do
    echo "${var[$i]}";
done

And here's the output when I run the Bash:

foo bar baz moo
4
foo
bar
baz
moo 

The problem is, of course, the space. I've run into this problem before, and learned from this answer on Unix SE that I need to properly escape variables with double quotes to ensure that empty string items will show up in Bash arrays.

But that hasn't worked here. Just for comparison, when I run this code:

arr=(aa '' b 'bb')
echo "${arr[@]}"
echo "${#arr[@]}"
for i in "${arr[@]}"; do
    echo $i
done

I get this output:

aa  b bb
4
aa

b
bb

So I believe the problem comes from when I call the Python script - I don't think it's handling the whitespace properly.

I could make the Python so that it outputs a single list of everything it wants to print, like this ['foo', 'bar', '', 'baz'] etc. and use tr to get rid of the extra characters, but that gives me less flexibility in how I write the Python. I'd like the Python to be able to print from anywhere, and the Bash will correctly add the output to an array.

How can I set up the Bash and Python so that Python can pass empty strings to Bash from anywhere in the code, and the latter will recognise the empty string as a valid array element?

Lou
  • 2,200
  • 2
  • 33
  • 66
  • 1
    Your problem is in the line `var=($(python pyspace.py))`. That's an antipattern, don't do `array=( $(anything) )` ever. Instead, `readarray -t array < <(anything)` – Charles Duffy Dec 16 '20 at 16:44
  • See [BashPitfalls #50](http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_....29_.29). – Charles Duffy Dec 16 '20 at 16:44
  • you don't have space in `''` but empty string. – furas Dec 16 '20 at 16:44
  • And `echo "$i"`, not `echo $i`. – Charles Duffy Dec 16 '20 at 16:45
  • 1
    BTW, in general, `printf '%s\n' "${array[@]}"` is a better way to print each array element to a different line of output. – Charles Duffy Dec 16 '20 at 16:46
  • Also, note that double quotes only have effect for suppressing string-splitting when they're in a context that treats them as syntax, not when they're in a context that treats them as data. That means double quotes in the output of `pyspace.py` are just another character with no special behavior. – Charles Duffy Dec 16 '20 at 16:48
  • ...that distinction is also at the heart of [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050) (a very different thing than the above BashPitfalls link despite having the same number). – Charles Duffy Dec 16 '20 at 16:49

0 Answers0