Remote script over ssh execution issues.

If I execute below code I am able to get string from column8 and column10 about a process.

serverA1$> ps -ef | grep rotate | grep 'config' | awk '{print $8" "$10}'
/<Oracle_home>/ohs/bin/odl_rotatelogs -h:/<app_Home>/config/OHS/ohs1/component_events.xml_ohs1
/<Oracle_home>/ohs/bin/odl_rotatelogs -h:/<app_Home>/config/OHS/ohs1/component_events.xml_ohs2
/<Oracle_home>/ohs/bin/odl_rotatelogs -h:/<app_Home>/config/OHS/ohs1/component_events.xml_ohs3

servers

serverA1
serverB1
serverC1

But when I try to execute below script to execute same command on multiple servers, I am getting "0"s instead of column8 and column10. I think block of lines execution syntax does not like --> $8" "$10 in awk.

 
#!/bin/bash
for server in `cat servers` ; do
sudo ssh $server "bash -s" << EOF
echo "server=$server"
ps -ef | grep rotate | grep 'config' | awk '{print $8" "$10}'
EOF
done

How can I print output from each server in this format?

--> $server, $column8, $column10

A workaround would be to bring the output of ps back and run your awk locally, like so:

 
 ssh ... << EOF | awk '{print $8,$10}'
 ps -ef ...
 EOF
 

Of course, this is not a right solution, just a workaround. Others would probably show you how to properly deal with $ expansion in this case.

I suppose the here-document goes to the "sudo"-command, not the "ssh"-command.

Anyways, the command as you wrote it must be wrong (or, to be precise, overly complicated). Whenever a "grep" is piped into another "grep" and/or "awk" then something is to be done:

ps -ef | 'awk '/rotate/ { /config/ {print $8" "$10}}'

should do the same.

Btw. i suppose the "sudo" is there for the wrong purpose, because i doubt that only "root" is allowed to do a "ssh". You probably want to connect as "root", which you can achieve in two ways:

ssh root@"$server" .....
ssh -l root $server ...

I hope this helps.

bakunin

1 Like
ps -ef | 'awk '/rotate/ { /config/ {print $8" "$10}}'   # quote before awk causes error
 bash: line 2: unexpected EOF while looking for matching `''
bash: line 3: syntax error: unexpected end of file

 ps -ef | awk '/rotate/ { /config/ {print $8" "$10}}'   # causes below error
 awk: /rotate/ { /config/ {print " "0}}
awk:                     ^ syntax error

 ps -ef | awk '/rotate/ {print $8" "$10}' # causes below empty result..
 0
 0
 0

Please help with this..

On a system where the ps -ef output conforms to POSIX standard requirements, the command:

ps -ef|awk '/rotate/ && /config/{print $8,$10}'

would print the command name and the 2nd argument passed to that command for any commands that contained the strings rotate and config , but that doesn't seem to be what you're showing us. Also note that the standards allow the command and its arguments to be truncated to an implementation-defined line length limit. (And, this could cause the strings you're looking for to be dropped from the ps output you're processing.) Your version of ps may provide options to set various line length limits to control that truncation. What output do you get from the command:

ps -ef|grep rotate

What are you expecting to find in fields 8 and 10 in the ps output?

Don, I am trying to find inventory of what OHS(oracle http server) instances are up and running on each server. We have around 200 ohs instances on 20 servers. I can get these details on each server using awk, please check my initial post. But same command does not work over "ssh" using $> ssh command <<EOF ... EOF syntax.
I think this syntax treats $ and "" differently than executing directly on the server.. How can get same result over SSH also?

You'll need to escape the $ signs lest they be expanded by your local shell. Try

ssh $server "bash -s" << EOF
ps -ef | awk -v"server=$server"  '/rotate/ && /config/ {print server, \$8" "\$10}'
EOF

Your code is now escaping special characters and printing server name. But it is also printing below line after each server's output.

 /<Oracle_home>/ohs/bin/odl_rotatelogs -h:/<app_Home>/config/OHS/ohs1/component_events.xml_ohs1
/<Oracle_home>/ohs/bin/odl_rotatelogs -h:/<app_Home>/config/OHS/ohs1/component_events.xml_ohs2
 serverA1 awk server=serverA1
 

How do I suppress that?

Or, if you quote EOF all expansion is disabled, this does leave you to resolve server on the remote side perhaps you could use hostname like this:

ssh $server "bash -s" << "EOF"
ps -ef | awk -v server=$(hostname -s) '/[r]otate/ && /config/ {print server, $8" "$10}'
EOF
server=$(hostname -s)

is resolving hostname to local hostname.

Below code is working.. but I am not sure how its working, can you explain?

 
 ps -ef | awk -v "server=$server" '/[r]otate/ && /config/ {print server, \$8" "\$10}'
 

it is filtering out

serverA1 awk server=serverA1

That's the awk process itself. It should not be matched due to the [r] brackets. Are you sure you used above command pipe?

Add a 1 between closing brace and closing quote and post the result.

1 Like

The quotes around "EOF" are important, they stop this local-side expansion of the $() command substitution eg:

$ hostname -s
MyPC

$ ssh MyServer <<EOF
   echo $(hostname -s)
EOF
MyPC

$ ssh MyServer <<"EOF"
  echo $(hostname -s)
EOF
MyServer
1 Like

This is really useful, I am having fun with this capability..