Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to connect to server B from server A using ssh and executing commands using some other user. However, when I try searching for a pattern in log file it says "cannot open log file" below is the sample code

ssh  -t user@hostname <<EOF
sudo su - someotheruser
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ $a -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi 
EOF

once I run the script, it says, unable to open "tail........."

I can't stay logged in on server B and run multiple commands.

share|improve this question
1  
Crawl before you walk; walk before you run.  ssh user@hostname command looks like a good start; now try it with a simple command (like id or ls) and build up to more complicated things.  That makes it easier to figure out where your problem is coming from.  But — spoiler alert — you're saying … < tail … and you're getting an error message that says unable to open "tail".  See a connection there? –  Scott Apr 2 at 5:47

3 Answers 3

If statements are not commands and need to be interpreted by a shell. You can try this. Create a local script

a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
[ $a -eq 0 ] && echo "Success" || echo "Faiilure"

and invoke the bash shell to execute these commands

ssh  -t user@hostname 'echo "pass" | sudo -Sv && bash -s' < script.sh
share|improve this answer
    
Why would the OP need to run sudo on the remote host when he's already sshing as a user other than the one he's logged in as on the local host? –  Scott Apr 2 at 5:50
    
@Scott I too had the same thought before, but then if the /somepath/application.log was only accesible by root user? He may not necessarily want to login as root on the remote server. –  rahul Apr 2 at 5:59

From what you described, I think there are two problems. First, you don't need that <. According to manual page of ssh, the string following the hostname will be immediately recognized as command executed at remote. To perform multiple commands, you can put them all into a single quoted string. The string will be sent to remote and executed like a script.

ssh -t user@hostname 'tail -10 /somepath/application.log | awk \'/Agent Exited/ { print $3 }\'; if [ $a -eq 0 ]; then echo "Success"; else echo "Failure"; fi'
share|improve this answer

Think carefully about when each command is executed, where it runs, and what input it receives.

  1. First the here document is expanded. This means that the tail/awk pipe is executed on the local host, and the variable substitution $a as well.
  2. Then the ssh command is executed. It receives the expanded here document; these are commands that are executed in the remote shell.
  3. The remote shell is executed with no arguments, so it reads commands to execute from standard input. These commands include sudo, but possibly (depending on the shell) some of the following lines as well.
  4. The remote shell executes sudo su - someotheruser. This runs a shell as someotheruser which first reads and executes that user's .profile, then reads commands from its standard input. The standard input contains whatever the first remote shell did not read, which is somewhat unpredictable (it depends on the shell and how much it happened to read from its input pipe).
  5. The shell running as someotheruser runs the commands that it read, if any.
  6. The shell running as someuser executes the if command (if it's read it).

To avoid here document expansion, use quotes around the heredoc marker. To avoid the unholy mixture of standard inputs, use sh -c … or be explicit as to what the second remote shell receives as its input.

ssh  -t user@hostname <<'SSH_EOF'
sudo su - someotheruser <<'SU_EOF'
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi
SU_EOF
SSH_EOF

Do you really need to source someotheruser's .profile? If not, use sudo -u someotheruser. If you do, use sudo -i -u someotheruser. Ajust your sudoers rule accordingly.

Reading the log file is the only thing that requires elevated privileges, so it would make sense to only run the tail command as someotheruser.

ssh -t user@hostname <<'SSH_EOF'
a=`sudo -u someotheruser tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi
SSH_EOF

You'll make your life a lot easier if you don't mix privilege escalation methods. Instead of using sudo to switch from someuser to someotheruser, use SSH to localhost. Chaining two ssh commands is easy. Set up a key — you can even set up a key that only allows running a specific command like tail -10 /somepath/application.log. Define an alias in your .ssh/config to SSH through the someuser account:

Host hostname-someotheruser
HostName hostname
UserName someotheruser
ProxyCommand ssh someuser@hostname

Then run

a=$(ssh hostname-someotheruser tail -10 /somepath/application.log |
    awk '/Agent Exited/ { print $3 }')
if [ "$a" -eq 0 ] 
then
  echo "Success"
else
  echo "Failure"
fi
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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