Bash: Variable substitution in quoted string looks like something from the Twilight Zone
I've got a bash script that's reading essentially the output of telnet (actually socat to a unix domain socket).
while read -r LINE; do
if [ "$USER_DATA_FLAG" == "true" ]; then #Evaluates to false for the moment
...
else
printf "%s\n" "Variable> $LINE" >>$DEBUG_LOG
printf "%s\n" "Line xxxxz $LINE yxxxxx" >>$DEBUG_LOG
...
fi
done
This yields the following incomprehensible output:
Variable> >INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
yxxxxxxxxz >INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
Variable> OpenVPN CLIENT LIST
yxxxxxxxxz OpenVPN CLIENT LIST
The first printf statement works fine and shows exactly what I expect based on my experience at the terminal. But the second printf statement goes nuts, reverses the order of开发者_运维知识库 some the characters and prints $LINE entirely in the wrong place!
$LINE
has a \r
in it, which is sending the cursor back to column 1. Use parameter substitution or tr
to remove it.
$ foo=$'1\r23'
$ echo "$foo"
23
$ echo "${foo/$'\r'/}"
123
This will ramble on a bit. The first thing I noticed was this:
printf "%s\n" "Variable> $LINE" >>$DEBUG_LOG
And I immediately think, "this is C code." In shell programming, printf
is somewhat an odd tool which is sometimes useful, unlike the printf
in C, which is the first thing you reach for when your printing something out. Try this instead:
echo "Variable> $LINE" >>$DEBUG_LOG
The other problem is potentially with telnet. If you parse telnet output in a shell, you're going to get some characters you don't want -- carriage returns, for example. The default value of IFS
for bash
is <space><tab><newline>
, which will NOT catch carriage returns and the carriage returns WILL mess with the location of characters in your terminal.
Ideally, you would get a proper telnet client and use it non-interactively. However, in a pinch, you can do this:
while tr -d '\r' | read -r LINE; do
...
This will strip out carriage returns -- but there could still be other telnet junk in there, including WILL/WONT/DO/DONT commands, and NUL bytes.
精彩评论