4

Look at this very basic Bash script:

#!/bin/bash
while read l
do
  echo $l
  echo "next one"
done <<< $(ps aux)

I have several processes on my computer, and the ps aux command works fine in the terminal.

I only get one iteration in the loop and ps command output is given on the same line. Why doesn't it work as intended?

Bob5421
  • 173
  • Couldn't replicate. Running that script on my system (bash v4.4) returns the same multi-line results from both the command line and as a script. Note: it'd be simpler to change while ... done <<< $(ps aux) to ps aux | while ... done. – agc Mar 26 '20 at 08:55
  • This is strange. Do you know if a configuration or environnement variable can impact this behaviour ? – Bob5421 Mar 26 '20 at 08:58
  • Are you using some old version of bash, like 3.2? –  Mar 26 '20 at 09:25
  • Let's compare set -o outputs. On my system printf '%x\n' $((2#$(set -o | rev | cut -c 1 | tr 'fn' '01' | tr -d '\n'))) outputs the hex summary of 31d4000. (That is it takes a list of "on/off" values, converts 'em to binary, then to a single hex value.) – agc Mar 26 '20 at 09:27

1 Answers1

9

In bash versions < 4.4-beta you need to add double quotes:

#!/bin/bash
while read l
do
  echo $l
  echo "next one"
done <<< "$(ps aux)"

See:


In general, I think it is better to use process substitution:

#!/bin/bash
while read l
do
  echo $l
  echo "next one"
done < <(ps aux)

(To avoid issues, you might want to use IFS=).

or even better, use a program specialized for reading files or input line by line like e.g. awk.

ps aux | awk '{print $0; print "next one"}'
pLumo
  • 22,565
  • Thanks but why quotes are needed on some system and not on others ? – Bob5421 Mar 26 '20 at 09:25
  • 3
    @Bob5421 because that was a bug which was fixed in newer versions of bash. Nowadays <<< $(...) should be identical to <<< "$(...)" (specifically when used with <<<, not $(...) in general). I can reproduce your problem with bash-3.2, but not with newer versions. –  Mar 26 '20 at 09:26
  • Not with bash-4.4 ;-) So the change probably happened just between the 2 versions. The new behaviour is documented in the manpage: "[n]<<<word ... Pathname expansion and word splitting are not performed." –  Mar 26 '20 at 09:33
  • 1
    You don't need my permission ;-) –  Mar 26 '20 at 09:36
  • Updated the answer, thanks! – pLumo Mar 26 '20 at 09:49
  • Yeah.. can reproduce in bash 4.2. Thanks. – WesternGun May 27 '22 at 14:50