2

My goal is to initialize multiple bash variables from the output of one single command. Specifically, line i should be the value of variable i. Example:

My command is a Python program with the name init.py:

if __name__ == '__main__':
  print("Value of A")
  print("Value of B")
  print()
  print("Value of D")

Desired outcome:

echo "A='$A', B='$B', C='$C', D='$D'"
# --> A='Value of A', B='Value of B', C='', D='Value of D'

What I then tried without success:

read A B C D < <(python init.py)
# --> Effect: A='Value', B='of', C='A', D=''

read -d$'\n' A B C D < <(python init.py)
# --> Effect: A='Value', B='of', C='A', D=''

IFS=$'\n' read A B C D < <(python init.py)
# --> Effect: A='Value of A', B='', C='', D=''

IFS=$'\n' read -d$'\n' A B C D < <(python init.py)
# --> Effect: A='Value of A', B='', C='', D=''
  1. How to solve this problem?
  2. How to generalize this to other separators, such as the Null byte \0?

1 Answer 1

5

If you have an empty line, using IFS won't work, because multiple \n are squeezed.

However, you can use readarray:

readarray -t arr < <(python init.py)
echo "A='${arr[0]}', B='${arr[1]}', C='${arr[2]}', D='${arr[3]}'"

Add -d '' to delimit by \0:

readarray -d '' -t arr < <(python init.py)

From man bash:

-d The first character of delim is used to terminate each input line, rather than newline. If delim is the empty string, mapfile will terminate a line when it reads a NUL character.

1
  • Thanks, that'll work. Can I use \0 as delimiter too? Commented Mar 23, 2021 at 8:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .