enthuguy
asked on
Shell script to handle SSH return value
HI,
I perform SSH to a remove linux server with a private key. Since I have a large pool of servers to ssh. I have also have two private keys used by these servers. but only subset uses the 2nd private key.
My request now is
I would like to add a logic in my calling shell script... if ssh failed with below error. Try with the 2nd private key. please help
Guessing, should handle the return code and determine to use 2nd key.
and this is how I connect
I perform SSH to a remove linux server with a private key. Since I have a large pool of servers to ssh. I have also have two private keys used by these servers. but only subset uses the 2nd private key.
My request now is
I would like to add a logic in my calling shell script... if ssh failed with below error. Try with the 2nd private key. please help
Guessing, should handle the return code and determine to use 2nd key.
Permission denied (publickey,keyboard-interactive)
and this is how I connect
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem ec2-user@${targetIP}
@enthuguy
I have written sample script at my system:
cat 29176838.sh
We need to use \" when we are using any quote.
Example1:
Example1:
other wise $? from localhost will be passed to remote host.
Example3:
referring return value of $? due to delete.txt
Use \" when using doublt quotes from ssh
I have written sample script at my system:
cat 29176838.sh
#/bin/bash
targetIP=123.456.78.910
USERNAME=root
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem $USERNAME@${targetIP} "pwd;if [ \"\$?\" != \"0\" ];
then
echo \"Using: ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP}\";
ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP} \"pwd\";
else
echo else;
fi"
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem $USERNAME@${targetIP} "/usr/bin/pwd"
a)We need to use \" when we are using any quote.
Example1:
$ /usr/bin/ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem murugesandins@123.456.78.910 "pwd"
/home/murugesandins
After using a command we can use \$? to validate if previous command executed successfully or notExample1:
$ /usr/bin/ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem murugesandins@123.456.78.910 "ls -ld asd >/dev/null 2>&1;if [ 0 -ne \$? ];then echo asd file not found;fi"
asd file not found
We have to use \$? when passing parameter to sshother wise $? from localhost will be passed to remote host.
Example3:
$ /usr/bin/ls -ld delete.txt
/usr/bin/ls: delete.txt: No such file or directory
$ /usr/bin/ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem murugesandins@123.456.78.910 "echo \"Value of => $? passed from localhost at remote host\""
Value of => 2 passed from localhost at remote host
$ /usr/bin/ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem murugesandins@123.456.78.910 "echo \"Value of => $? passed from localhost at remote host\""
Value of => 2 passed from localhost at remote host
$ /usr/bin/ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem murugesandins@123.456.78.910 "echo \"Value of => $? passed from localhost at remote host\""
Value of => 0 passed from localhost at remote host
Value of => 2 passed from localhost at remote hostreferring return value of $? due to delete.txt
Use \" when using doublt quotes from ssh
@enthuguy
Sample version0.1 script output:
I updated that code again
Sample version0.1 script output:
$ cat ./29176838.sh
#/bin/bash
targetIP=123.456.78.910
USERNAME=root
#Change USERNAME as per your requirement
#Change targetIP as per your requirement
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem $USERNAME@${targetIP} "ls NotFound.txt >/dev/null 2>&1;if [ \"$?\" != \"0\" ];
then
echo \"Using: ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP}\";
ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP} \"pwd\";
else
echo else;
fi"
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem $USERNAME@${targetIP} "pwd"
$ ./29176838.sh
else
/home/murugesandins/experts_exchange
I updated that code again
$ cat ./29176838.sh
#/bin/bash
targetIP=123.456.78.910
USERNAME=root
#Change USERNAME as per your requirement
#Change targetIP as per your requirement
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem $USERNAME@${targetIP} "ls NotFound.txt >/dev/null 2>&1;if [ \"\$?\" != \"0\" ];
then
echo \"Using: ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP}\";
ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem $USERNAME@${targetIP} \"pwd\";
else
echo else \$Ret;
fi"
$ ./29176838.sh
Using: ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem root@123.456.78.910
/home/murugesandins/experts_exchange
You code should work.
Try changing to this...
See what the actual value of $res might be. For failures, normally you'll see a non-zero error code.
Try changing to this...
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem ec2-user@${targetIP}
res=$?
echo "# res: $res"
if [ "$res" != "0" ]; then
ssh -o StrictHostKeyChecking=no -i ~/.ssh/secondkey.pem ec2-user@${targetIP}
fi
See what the actual value of $res might be. For failures, normally you'll see a non-zero error code.
ASKER
Thanks so much murugesandins, that was very details. Really appreciate your time
Just wanted to provide the actual script syntax I execute. Do you think, I can still use dev/null. please help
Just wanted to provide the actual script syntax I execute. Do you think, I can still use dev/null. please help
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem ec2-user@${targetIP} 'bash -s' < ${scriptsHome}/dummy.sh "\"${var2}\" \"${var1}\" \"${type}\" \"${NasRemotePath}\" \"${var3}\""
@enthuguy
Can you describe your requirement in detail?
I am not sure about your requirement:
Replace 123.456.78.910 murugesandins to required IP/username
Can you describe your requirement in detail?
I am not sure about your requirement:
#!/bin/bash
targetIP=123.456.78.910
USERNAME=murugesandins
ssh -o StrictHostKeyChecking=no -i ~/.ssh/firstkey.pem ${USERNAME}@${targetIP} 'if [ -z "${scriptsHome}" ];\
then
scriptsHome=/home/murugesandins
fi
if [ -f ${scriptsHome}/dummy.sh ]
then
if [ -z "${var2}" ]
then
var2="hai2"
fi
if [ -z "${var1}" ]
then
var1="hai1"
fi
if [ -z "${var3}" ]
then
var3="hai3"
fi
if [ -z "${type}" ]
then
type="type"
fi
if [ -z "${NasRemotePath}" ]
then
NasRemotePath="NasRemotePath"
fi
echo "Output after executing following command:"
echo ${scriptsHome}/dummy.sh "\"${var2}\" \"${var1}\" \"${type}\" \"${NasRemotePath}\" \"${var3}\""
${scriptsHome}/dummy.sh "\"${var2}\" \"${var1}\" \"${type}\" \"${NasRemotePath}\" \"${var3}\""
fi'
Sample output:$ ./29176838_version2.sh
Output after executing following command:
/home/murugesandins/dummy.sh "hai2" "hai1" "type" "NasRemotePath" "hai3"
/home/murugesandins
"hai2" "hai1" "type" "NasRemotePath" "hai3"
$ cat /home/murugesandins/dummy.sh
#!/bin/bash
pwd
echo $@
Replace 123.456.78.910 murugesandins to required IP/username
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Thank you and welcome.
Let us know if having further statement at current query ?
Let us know if having further statement at current query ?
I think your problem may be that ssh is trying your first identity file, and if it fails, prompting for a password.
To avoid this, by forcing the use of the identity file, set the ChallengeResponseAuthentic ation and PasswordAuthentication options to no. I also do a trial run, by adding the "-n" option - this doesn't try to run a remote command, just connects and disconnects again. It allows me to work out which key worked, and to use that later to run the actual remote command you are trying to run. I report an error if neither key worked (also if the remote host was down).
Couple of extra changes. I've used the mathematical test for the response ($? -eq 0) rather than the string test (!=) you used. We *know* that $? will be a number! Also the "1>&2" will redirect the standard output of the "echo" command to standard error.
Edit: Forgot the "-n" options on the two "test" ssh calls! There shouldn't be one on the last call, since that one *does* want to do work on the remote host.
To avoid this, by forcing the use of the identity file, set the ChallengeResponseAuthentic
VALID_KEY=""
ssh -n -o StrictHostKeyChecking=no -o ChallengeResponseAuthentication=no -o PasswordAuthentication=no -i ~/.ssh/firstkey.pem ec2-user@${targetIP}
if [ $? -eq 0 ]; then
VALID_KEY=firstkey.pem
else
ssh -n -o StrictHostKeyChecking=no -o ChallengeResponseAuthentication=no -o PasswordAuthentication=no -i ~/.ssh/secondkey.pem ec2-user@${targetIP}
if [ $? -eq 0 ]; then
VALID_KEY=secondkey.pem
fi
fi
if [ ${VALID_KEY} ]; then
# Here do the actual ssh command you want to use (where I have "remote_command")
ssh -o StrictHostKeyChecking=no -i ~/.ssh/${VALID_KEY} ec2-user@${targetIP} remote_command
else
echo "ERROR: No valid key found for host ${targetIP}" 1>&2
fi
Couple of extra changes. I've used the mathematical test for the response ($? -eq 0) rather than the string test (!=) you used. We *know* that $? will be a number! Also the "1>&2" will redirect the standard output of the "echo" command to standard error.
Edit: Forgot the "-n" options on the two "test" ssh calls! There shouldn't be one on the last call, since that one *does* want to do work on the remote host.
One other thing. Is the original code you posted exactly as run? *Any* command (even an "echo") between the "ssh" and the "if" will overwrite the return code from the ssh. If you want to test a return code, the best thing is to store it in a variable in the line immediately after the command.
ASKER
Thanks all
You're welcome!
Good luck!
Good luck!
$ echo wELcOME | /usr/bin/wc >/dev/null
ASKER
Open in new window