2

I'm trying to ssh into a server and get the system uptime using a specific command but it's failing to execute.

this would work locally on almost all unix systems

startuptime=`uptime | awk '{print $2,$3,$4,$5}'` && startuptime1=${startuptime%,} && startdayshours=${startuptime1%%:*}' Hours, ' && startminutes=${startuptime1##*:}' Minutes' && echo 'System Uptime -' $startdayshours$startminutes `date`

but if i do this, it won't work ( no matter how i change/add escape chars or $() or `` or ' " ' " ' quotes etc..)

ssh user@server "startuptime=`uptime | awk '{print $2,$3,$4,$5}'`; startuptime1=${startuptime%,}; startdayshours=${startuptime1%%:*}' Hours, '; startminutes=${startuptime1##*:}' Minutes'; echo 'System Uptime -' $startdayshours$startminutes `date`"

P.S: i know it won't work with quotes cuz i need to escape the inner ones but it's just an example like ssh user@server command_goes_here

1

4 Answers 4

9

You have backticks in your command. That means they get run before the ssh command. Also, you are doing an assignment in your ssh command. You do not do anything with that assignment though. So, ssh probably assigns garbage to the startuptime variable that you never use.

What you really want is just the output from the uptime command on the remote server. You can then pipe that through your local awk and stuff to get what you want.

ssh user@server uptime | awk '{print $2, $3, $4, $5}'

If that works for you, you can then add in the rest of your commands.

You could even do

startuptime=$(ssh user@server uptime)
echo startuptime | awk '{print $2, $3, $4, $5}'

if you wanted to do further processing locally of that remove value.

3

You can simply put that command in bash file then run like below:

  • ssh user@server < script.sh
1

I agree with the suggestion that you should just get the uptime from the server and process that result locally.

However, the general solution for such tasks is that you have to quote everything that would be interpreted by the local shell. This includes the quotes themselves, the dollar signs, and the backticks (that are deprecated anyways).

1

Referring to Lewis's answer, It worked this way

script.sh with chmod +x

#!/bin/bash
running=$(ps aux | grep -v grep | grep "`basename "$0"`" | wc -l);
[[ $running > 2 ]] && exit;

declare -a servers=(
            "server1"
            "server2"
            "server3"
        )

for i in "${servers[@]}"
    do
    log_path="/path/to/log/folder/$i"
    if [ ! -f "$log_path" ]; then
        touch "$log_path"
    fi
    ssh_output=$(ssh user@$i uptime | awk '{print $2,$3,$4,$5}')
    startuptime=${ssh_output%,}
    startdayshours=${startuptime%%:*}' Hours, '
    startminutes=${startuptime##*:}' Minutes'
    echo 'System Uptime -' $startdayshours$startminutes `date` >> "$log_path"
done

and using cron I did the following:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * /path/to/script/script.sh

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .