Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

linux - Read line by line in Bash script

I want to do the following: Read a file line by line and use the line as a parameter.

FILE="cat test"
echo "$FILE" | 
while read CMD; do
echo $CMD
done

But when I do echo $CMD, it just prints cat test.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The best way to do this is to redirect the file into the loop:

# Basic idea. Keep reading for improvements.
FILE=test

while read CMD; do
    echo "$CMD"
done < "$FILE"

A redirection with < "$FILE" has a few advantages over cat "$FILE" | while .... It avoids a useless use of cat, saving an unnecessary child process. It also avoids a common pitfall where the loop runs in a subshell. In Bash, commands in a | pipeline run in subshells, which means variable assignments are lost after the loop ends. Redirection with < doesn't have that problem, so you could use $CMD after the loop or modify other variables inside the loop. It also, again, avoids unnecessary child processes.

There are some additional improvements that could be made:

  • Add IFS= so that read won't trim leading and trailing whitespace from each line.
  • Add -r to read to prevent backslashes from being interpreted as escape sequences.
  • Lower-case CMD and FILE. The Bash convention is that only environmental and internal shell variables are uppercase.
  • Use printf in place of echo which is safer if $cmd is a string like -n, which echo would interpret as a flag.
file=test

while IFS= read -r cmd; do
    printf '%s
' "$cmd"
done < "$file"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...