2

There is a simple log file /tmp/test.log

2019-12-09 15:28:12 UTC [6308] App1
2019-12-09 15:29:08 UTC [1246] App2
2019-12-09 15:30:57 UTC [5541] App3

There is a simple bash script /tmp/test.sh

#!/bin/bash
# 
while read line
do
    echo $line
done < /tmp/test.log

If I run this script locally it works as expected:

$ /tmp/test.sh
2019-12-09 15:28:12 UTC [6308] App1
2019-12-09 15:29:08 UTC [1246] App2
2019-12-09 15:30:57 UTC [5541] App3

but if I run this script via ssh I'm getting something unexpected:

$ ssh 127.0.0.1 "/tmp/test.sh"
2019-12-09 15:28:12 UTC 0 3 App1
2019-12-09 15:29:08 UTC 1 App2
2019-12-09 15:30:57 UTC 1 App3

Does anybody know why?

jakub-olczyk
  • 113
  • 6

1 Answers1

3

I think there are a couple of separate things interacting here to cause the confusing result. Here's my best guess explanation.

The value you have for the important IFS variable is probably 20 09 0a (these are the hex codes , for space, tab, newline). This has important consequences on the echo (and also read statements). (use echo -n "$IFS" | hexdump to see values).

The read command will read each line from the file, and add them all into the line variable. It will actually tokenise each line, and add each word to line.

The echo statement will cause evaluation of the value in line. The shell will use IFS to separate the value into separate tokens, and then pass them all to echo, which will print them, separated by spaces. I.e., there is a shell pre-processing step that is hard to observe.

The problem arises for tokens like [6308] etc. The square brackets are used for shell globbing, so when bash encounters something like [6308] it will try to match it to files in the current directory named like 6 or 3 or 0 or 8. So if you have two files named 0 and 3, it will match them both and return the string 0 3.

The reason you have different results when run locally as opposed to via ssh is likely just due to the current working directory in which the script is invoked. When run via ssh, it won't run from the your local current directory. To find the cwd used for the ssh invocation, just put a pwd near the top of your file. I'm guessing that the directory used via the ssh invocation has files named like 0 etc.

The simple fix is to prevent the shell processing the contents of $line, by enclosing it with quotes, as in echo "$line" . You could also adjust IFS, but quoting the string is usual practice.

Darren Smith
  • 2,261
  • 16
  • 16