How to Use Execute Shell Script -- With Input From

Correct, in this particular instance. More generally, printf, like echo, will delimit at any character defined in the $IFS shell variable, which I think defaults to $'\n \t', i.e. newline, space, and tab. In hindsight, using single characters was a bit of a limited test case. Were the input to stdin this:

A B C
1 2 3
a b c

that same expression from earilier would produce:

A	B	C	1	2	3	a	b	c

This might be useful in some situations, but not ideal for our needs here. However, you can set the $IFS variable to easily ensure you get the desired result:

IFS=$'\n'
printf '%s\t' $(<\dev\stdin) 

Output:

A B C	1 2 3	a b c

If you’re after a one-line method that lets you reference the data as variables as it's being read from stdin, I don’t think you can. The variables need to be read and assigned first, as far as know. Here are the different ways I can think of doing this, using the same stdin in each case:

stdin:

A B C
1 2 3
a b c

1. cat

IFS=$'\n' # set the IFS variable to delimit at newlines only
vars=( $(cat) ) # the ($(...)) notation creates an array
printf '%s\n' "vars[0] : ${vars[0]}" "vars[1] : ${vars[1]}" "vars[2] : ${vars[2]}"

output:

vars[0] : A B C
vars[1] : 1 2 3
vars[2] : a b c

2. /dev/stdin (esesntially the same as cat)

IFS=$'\n'
vars=( $(</dev/stdin) )
printf '%s\n' "vars[0] : ${vars[0]}" "vars[1] : ${vars[1]}" "vars[2] : ${vars[2]}"

output:

vars[0] : A B C
vars[1] : 1 2 3
vars[2] : a b c

3. read

IFS=$'\n' read -d \n -a vars
printf '%s\n' "var[0] : ${vars[0]}" "var[1] : ${vars[1]}" "var[2] : ${vars[2]}"

output:

vars[0] : A B C
vars[1] : 1 2 3
vars[2] : a b c

Perhaps someone else (like @ccstone who is more experienced with shell scripting than I) might be able to offer additional insight into this. I actually don't use bash as my main shell, and only write bash scripts for use in Keyboard Maestro. I use FiSH, which in many ways, is a lot more intuitive, so lets me process the stdin from above using the read command like this:

read --line var1 var2 var3

without having to fuss with the $IFS business. It even lets me do shorthand like this:

read --line var{1,2,3}

which is functionally identical to the previous statement


And, of course you know how do bring in KM variables do the shell action with $KMVAR_{var}.