Retrieving the result of a bash command run from ssh into a variable - linux

The following command runs well when i run it localy on the dsired machine:
app_name=*some_proccess_name*
pid=`pgrep $app_name | tail -n 1`
But when i run it in the following way, from a remote pc using ssh it dosn't work:
pid=$(ssh $USER_NAME#$HOST_NAME "echo `pgrep $app_name | tail -n 1`")
The value of pid afterwards is just blank. I am not sure what's wrong (just to clarify i have tried several processes names that are all running on the target pc- that's not the problem ).
P.S when i run the command without echo, like that, i just get stuck inside the remote pc and have to use exit in order to get unstuck and return to my local pc:
pid=$(ssh tester#mir1 "`pgrep indicator-apple | tail -n 1`")

Less is more
pid=$(ssh tester#mir1 pgrep indicator-apple \| tail -n 1)

Related

change directory is not working through script but working directly on machine

I am trying to run this command through script doing ssh and it is only executing cd command.
cd $(ls | tail -1)
While it is working directly on the machine.
I can just assume here, but are you quoting correctly? When you run ssh user#host cd $(ls | tail -1) the command substitution is performed on the client, not the server.
You have to use:
ssh user#host 'cd $(ls | tail -1)'
That mentioned, your command doesn't do anything. cd would change the working directory on the server and then the ssh session is terminated.

How to pass the output from one command as value of argument of the next command

I want to pass the result of a command as a value of an argument of the next command. I know there is xargs and pipe | but those don't really help.
I want to run the command tail -f --pid=$REMOTE_PID logs where REMOTE_PID is the PID of a program which is running on a remote server. It writes digits from 1 to 30 in a log file and sleep(1). So I want to display simultaneously the digits coming from the log file on the local machine. All this is done in a script, not manually !!
Here is what I have done so far but can't get the correct PID. In the first command, I put the & to release the shell, so that I can run the next command
ssh user#host 'nohup sh showdigits.sh' &
ssh user#host 'PID=`pgrep -f showdigits.sh` && tail --pid=$PID -f logs'
These commands work but I get several PIDs before gitting the right one:
tail: cannot open '8087' for reading: No such file or directory
tail: cannot open '8109' for reading: No such file or directory
==> logs <==
1
2
3
...
I tried another code :
ssh user#host 'nohup sh showdigits.sh' &
ssh user#host "ps -ef | awk '/[s]howdigits.sh/{print $2}' > pid && tail --pid=`cat pid` -f logs"
I get this error :
cat: pid: No such file or directory
tail: : invalid PID
I want to have the only one PID of the script showdigits.sh and pass it to tail. Maybe is there a simpler solution ?
Thank you
Your strategy is:
Start a process
Disconnect and forget about it
Reconnect and try to find it
Follow it
You can simplify it by dropping step 2 and 3 entirely:
ssh user#host '
nohup sh showdigits.sh &
tail --pid=$! -f logs
'
(NB: using sh to run a script is a worst practice)
your grep is matching more than 1 result. first match is assigned to --pid= and others are interpreted as file names.
you have to pass it through head (or tail) before processing (depending on which pid you want)
PID=$(pgrep -f showdigits.sh | head -n1)

Bash for loops on a remote server

I am attempting to run multiple commands via a bash script on a remote server. specifically, the for loop to be run on the remote server is giving me issues. I suspect it is because I don't know how to properly escape characters or use $().
Below is the code.
ssh (user)#(server) <<EOF
sudo su - (username)
whoami
'for e in $(`ls -lrt /usr/jboss/jbosseap | awk '{print $9}' | grep multichannel`);
do
echo "$e";
done'
Removing user and server names for obvious reasons. Just concentrate on the for loop. when I run that for loop command line (without the $()) its works fine. Just not sure how to nest it in a remote call.
Thanks very much for any and all help!
If you've got a complex script that you're trying to run over ssh you're going to be better off putting that script in a file and piping that file into ssh like:
cat remote_script.sh | ssh user#host
or:
cat remote_script.sh | ssh user#host sudo -u username
And now you don't have to worry about N levels of escaping.
You can run it as below .
here file "list " includes your list of nodes and script should be present in all nodes
for i in $(cat list ) ;do ssh -o StrictHostKeyChecking=no $i "/path/your_script" ;done

Starting sshd automatically if it is down/failed

I am trying to create a Bash .sh script for a cronjob that starts the OpenSSH server if it is down or failed.
Last night the SSH server was down and when I tried to access it today (from work) the connection was refused ofc.
No traces in the /var/log/messages for the failure.
So the question is - how to determine is sshd running so if it is not to "sudo service ssh start" it?
Thanks in advance!
Fellas, I believe that I have managed to do the task:
#!/bin/bash
service="ssh"
if (( ! $(sudo service ssh status | cut -d" " -f 3 | cut -d"." -f 1) == "running" ))
then
sudo /etc/init.d/ssh restart
fi
I have changed the LogLevel to Verbose, I hope the next time I will track more clues regarding the failure of the sshd.
I'm implementing the following:
[ $(sudo service ssh status | grep running | grep -v grep | wc -l) == 0 ] && sudo /etc/init.d/ssh restart
as other people said It's Incorrect to start it without finding what caused this problem, but I wrote some help for the script you want
first you should check the status of your openssh server for example:
ps -aux | grep ssh
then write an if to check if it is down or not
you can check it with the result of previous step.
if that was down, start it
sudo service ssh start

Open as many terminals as the number of ssh-s logged out and close the terminals in which ssh-s where logged out

There are several terminals in a single localhost in which I have ssh-ed into the same user and same IP address. I want to find all the terminals in which a remote host has been logged, terminate all processes running in those and log out of that remote host. I succeeded using the following shell script.
#Find list of terminals in which the remote host is logged in.
openedTerminals=`ssh $user#$publicIP "ps -aux | grep -i $user#pts | grep -v grep | cut -d' ' -f 3"`
#close all the ssh sessions to that remote host
i=1
terminalPID=`echo $openedTerminals | cut -d' ' -f $i`
while [[ -n "$terminalPID" ]]
do
ssh $user#$publicIP "kill $terminalPID"
i=`expr $i + 1`
terminalPID=`echo $openedTerminals | cut -d' ' -f $i`
done
I used the following command to open a new terminal and ssh into a remote host which worked fine when executed from the command prompt:
gnome-terminal -window-with-profile=NOCLOSEPROFILE -e "ssh -X $user#$publicIP"
Apart from doing the work of the 1st code, I want to open a new terminal (by ssh-ing into another remote machine) for every remote machine which was terminated by the 1st code. So I tried to insert the above command in the 1st code as:
#Find list of terminals in which the remote host is logged in.
openedTerminals=`ssh $user#$publicIP "ps -aux | grep -i $user#pts | grep -v grep | cut -d' ' -f 3"`
#close all the ssh sessions to that remote host
i=1
terminalPID=`echo $openedTerminals | cut -d' ' -f $i`
while [[ -n "$terminalPID" ]]
do
ssh $user#$publicIP "kill $terminalPID"
gnome-terminal -window-with-profile=NOCLOSEPROFILE -e "ssh -X $newUser#$newPublicIP"
i=`expr $i + 1`
terminalPID=`echo $openedTerminals | cut -d' ' -f $i`
done
But this starts running in an infinite loop and opens infinite number of new terminals.
Please tell me where I am wrong and suggest a way to correct it in order to get the desired solution.
Also, I wish to add a command in the same shell script (1st code) to close the terminals in which the remote machine was logged out. Can anyone please guide me on this?
Thanks in advance,
Saeya
When only one terminal which is ssh-ed to the remote machine is opened, this runs in an infinite loop because of the "cut" command. If there is a separate case to handle one terminal this will work fine.

Resources