0

I have a simple command to return the uptime/load average from a list of servers, and am using awk to format the output:

for i in $(cat servers); do ssh $i -qt "uptime" | awk -F\, -v host=\"$i\" '{ print host, $4, $5, $6 }'; done

This works reasonably well:

"server1"   load average: 0.22  0.37  1.99
"server2"   load average: 0.22  0.37  1.99
"server3"   load average: 5.96  4.39  5.66

Unfortunately, the last field must contain a carriage return, meaning it can't appear anywhere but the end of the command. For example:

for i in $(cat servers); do ssh $i -qt "uptime" | awk -F\, -v host=\"$i\" '{ print host, $6, $5, $4 }'; done

Output:

0.64   load average: 0.17"  1.74
0.64   load average: 0.17"  1.74
0.78   load average: 0.15"  3.24

How can I remove the carriage return from either a) the end of the input, or b) the end of field $6?

  • 2
    try removing the -t option from ssh – mosvy Oct 5 '18 at 14:50
  • This worked. Add it as an answer and I'll accept it. – toryan Oct 5 '18 at 16:42
3

You should remove the -t option from ssh in order to prevent generating the carriage return in the first place.

The -t option directs ssh to allocate a pseudo terminal on the remote machine, and if that terminal has the onlcr flag set (which is the default), every LF (\n) will be translated to CR/LF (\r\n) on output. The -t option is not needed unless a full-screen and/or interactive program is run, like vi or screen.

But if you really have to process lines terminated by CR/LF in awk, setting the record separator to CR/LF at the beginning of your script will do it fine. Example:

awk ... 'BEGIN{RS="\r\n"}{...}'

Also, if you want to remove a stray CR from a field in awk, you can use sub or gsub:

gsub("\r","",$6)
0

You can remove the trailing \r with sed

ssh $i -qt "uptime" | sed 's/\r$//' | awk ...
# ....................^^^^^^^^^^^^^

Additionally, for best practice, don't read lines from a file with for

  • Thanks for that. I tried rewriting the command to use while, but it doesn't work. Can you help? Command is while IFS= read -r i; do ssh $i -q "uptime" | awk -F\, -v host=\"$i\" '{ print host, $6, $5, $4 }'; done < servers – toryan Oct 5 '18 at 16:36
  • You need to modify the data between its creation (ssh uptime) and its consumption (awk). How does a while loop help with that? – glenn jackman Oct 5 '18 at 16:40
  • I don't know, I was following the instructions in your link. The original question was resolved by removing -t from the ssh command. – toryan Oct 5 '18 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.