4

If I execute a find command, with grep and sort etc. in the local command line, I get returned lines like so:

# find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g
0:0:line:1
0:0:line:2
0:0:line:3

If I execute the same command over ssh, the returned text prints without newlines, like so:

# VARcmdChk="$(ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g")"
# echo ${VARcmdChk}
0:0:line:1 0:0:line:2 0:0:line:3

I'm trying to understand why ssh is sanitising the returned text, so that newlines are converted to spaces. I have not yet tried output'ing to file, and then using scp to pull that back. Seems a waste, since I just want to view the remote results locally.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
sarlacii
  • 454
  • 7
  • 14

3 Answers3

8

When you echo the variable VARcmdChk, you should enclose it with ".

$ VARcmdChk=$(ssh ${VARuser}@${VARserver} "find tmp/ -iname status -exec grep 'last seen' {} \; | sort --field-separator=: -k 4 -g")
$ echo "${VARcmdChk}"
last seen:11:22:33:44:55:66:77:88:99:00
last seen:00:99:88:77:66:55:44:33:22:11

Note that I've replaced your xargs for -exec.

Bayou
  • 3,293
  • 1
  • 9
  • 22
2

Ok, the question is a duplicate of this one, Why does shell Command Substitution gobble up a trailing newline char?, so partly answered.

However, I say partly, as the answers tell you the reasons for this happening as such, but the only clue to a solution is a small answer right at the end.

The solution is to quote the echo argument, as the solution suggests:

# VARcmdChk="$(ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g")"
# echo "${VARcmdChk}"
0:0:line:1
0:0:line:2
0:0:line:3

but there is no explanation as to why this works as such, since assumption is that the variable is a string, so should print as expected. However, reading Expansion of variable inside single quotes in a command in Bash provides the clue regarding preserving newlines etc. in a string. Placing the variable to be printed by echo into quotes preserves the contents absolutely, and you get the expected output.

sarlacii
  • 454
  • 7
  • 14
0

The echo of the variable is why its putting it all into one line. Running the following command will output the results as expected:

ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g"

To get the command output to have each result on a new line, like it does when you run the command locally you can use awk to split the results onto a new line.

awk '{print $1"\n"$2}'

This method can be appended to your command like this:

echo ${VARcmdChk} | awk '{print $1"\n"$2"\n"$3"\n"$4}'

Alternatively, you can put quotes around the variable as per your answer:

echo "${VARcmdChk}"