0

In this script I was just wondering why the double quotes are necessary around the variable $line

$cat script1
#!/bin/bash
exec 3<$1
exec 4<$2
exec 5>$3
while read line <&3
do
      echo "$line" >&5
done
while read line <&4
do 
      echo "$line" >&5
done
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
R. Lee
  • 63
  • 5

1 Answers1

2

You need quotes around line if you don't want spaces (IFS characters, default spaces, tabs and newlines) to expand. Observe:

printf "a                   b\n" | 
while read line; do 
    echo $line
done

this will output:

a b

With qoutes:

printf "a                   b\n" | 
while read line; do 
    echo "$line"
done

will output:

a                   b

Quotes prohibit shell expansion. Grab a good read on quotes. Also read about IFS and be aware of read delimiter -d option and -r option.

If you whish to read from file, preserving leading and trailing whitespaces and the whole line, see here and use:

while IFS= read -r line; do
    echo "$line"
done

Also note that using while read loops to parse files is very slow on bash. Try to use bash commands and moreutils and standard unix commands to parse files. If you really need to parse file line by line, xargs and parallel are good programs for that. The script you presented may be just substituted by cat "$1" "$2" >"$5" (or more like cat "$1" "$2" | sed 's/^[ \t]*//;s/[ \t]*$//' > "$5", because leading and trailing whilespaces will not be preserved).

Also quote your variables. The exec 3<$1 will fail if someone cals your function with file with spaces in the name, like: ./script1 "filename with spaces.txt". Use exec 3<"$1".

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    Thank you so much for explaining, showing the differences, and the tip. I will make sure to quote my variables. – R. Lee Oct 10 '18 at 08:52