How to retrieve bash shell return code in Windows Server with ssh? - linux

We have a remote bash shell script on a Linux Server.
We have a local Windows Server 2008 box to use ssh to execute the remote shell script.
We cant seem to get the remote return code.
we tried
ssh remote "./remote_shell.sh test" <-- returns 1
echo %errorlevel%
How do we do it right ?
Thanks

If it's really bash; then the return code is $?
ssh remote "./remote_shell.sh test"
echo $?

ssh remote "./remote_shell.sh test; echo $?"
The echo command will print the exit status of the preceding command. It would be necessary to parse the number from the ssh output. You could make that a little easier by tagging the value:
ssh remote "./remote_shell.sh test; echo exit value was: $?"

Related

how to write a function in bash_profile

how can we write a simple regular function which i can put in my bashprofile
which can be used to secure console to any host i want.
but my secure console has to go through a jump host. that is the issue.
function func_name () {
ssh jumphostname;
sc $hostname # from jump host secure console to another host given as input from terminal
}
this function only making to login in to jump host but not to secureconsole in to another host from there.
-bash-4.1$func_name host.me.com
should give me console to host.me.com via jumphost
is function for this not possible?
do i have to write a script?
Here's how I do it.
Create a functions folder at home
Write my function as a shell script
Reference the file as an alias in my bash_profile
Reset the source
Example
mkdir ~/.functions
echo '#!/bin/bash
echo $1' > ~/.functions/ekho
echo 'alias ekho="sh ~/.functions/ekho"' >> ~/.bash_profile
source ~/.bash_profile
Now you can call your method from any location for ever ever.
ekho "Wow"
You should not use commands in a test [ ] unless you simulate a variable with $( ) arround the commands. Still not sure SSH will return something to the test. SSH needs the TTY you like connect to, and not the TTY you in at. This will causes problems!
An example without SSH ...
suleiman#antec:~$ if [ "$(cat ~/test.txt)" ]; then echo "Hello World"; else echo "failed"; fi
Hello World
suleiman#antec:~$ if [ "$(cat /this/file/dont/exsist 2>/dev/null)" ]; then echo "Hello World"; else echo "failed"; fi
failed
Addition:
-bash: sc: command not found
This means you have NOT installed the spreadsheet on the host.
This function only making to login in to jump host but not to
secureconsole in to another host from there.
What you trying to do ?
Do you know what SSH does ?
It opens remote TTYs, or with other words: it opens a remote secure console.
You cant run a script and put somewhere a ssh login in it, and then think all code after that will be in the new console, neither will that happen.
You can run ssh on a console, so you get your own TTY and put some commands in it. Or you use ssh in combination with some commands in a script, like
ssh user#host echo "Hello World!"
You can also pass some variables or text though ssh via
echo "Hello World!" | ssh user#host cat
There isnt much more you can do with it and you shouldn't!
I would write this
con.sole() {
if ! ssh -T jumphostname true; then
printf 'Jump host "%s" not available.\n' jumphostname >&2
return 1
fi
sc "$#"
}
The square brace isn't part of the if statement syntax. It is a separate command, the same as test.
Below link would help you to go ahead
ssh username#host_address "command to execute"
For example output:
arul#OA2:~/work/images$ ssh arul#localhost echo "hai"
arul#localhost's password:
hai
arul#OA2:~/work/images$
ssh arul#localhost command will login and "echo hai" command printed in currently logged in prompt"
Citation: https://www.cyberciti.biz/faq/unix-linux-execute-command-using-ssh/
Its because you dont leave a whitespace between the if and the [...
The the correct sintax you want is...
function con.sole
{
if [ ssh jumphostname ]; then
sc $1;
else
echo "host not available"
fi
}
Greetings from Mexico! 🇲🇽

How to get exit code of remote command through ssh

I am running a script from remote machine via ssh:
ssh 'some_cmd;my_script'
Now, I want to store exit status of shell script on my local machine.
How can I do it?
Assuming nothing goes wrong with ssh itself, its exit status is the exit status of the last command executed on the remote host. (If something does go wrong, its exit status is 255.)
$ ssh remotehost exit 13
$ echo $?
13
I had same problem. I don't think the previous answers will work (at least, they did not work for me).
This is what worked for me: I ran my command and displayed the exit code and captured it in a variable.
Ensure you protect the $? sign with the escape sequence, \:
# retcode=$(ssh test#1.2.3.4 "grep -q test /etc/passwd ; echo \$? " 2>/dev/null)
# echo $retcode
# 1

How to logout an ssh session from within a perl script?

I have a perl script to do a second layer of authentication after an ssh shell is opened. It asks for password, and after n number of invalid attempts, the script should log out the user. This runs on a Debian system.
Now, the problem is that usually an ssh shell is closed interactively with the command exit.
When run from backticks, or system() from within a perl script, exit is not recognized as a valid command. So how can I logout the user from an ssh session, from within a perl script? The script is not responsible for the ssh session. It runs on the remote, and kicks in from .bashrc.
This is the relevant segment of code:
while ($actualpass ne $password) {
++$attempts;
if ( $attempts > $maxattempts ) {
`/bin/bash /root/ascii_breach`;
`/bin/bash exit`;
}
The /bin/bash exit obviously does not work.
Sounds like you have this a bit backwards. I think what you are doing is ssh'ing to the remote host which runs a shell, the shell runs perl and then perl wants to exit the shell. The better way of doing this is to ssh to the host to run the perl script directly. Only if the authentication passes should the perl script start up the shell.
You can configure sshd to run your authentication script in the authorized_keys file assuming that is how the user is getting in.
You could launch the authentication script, check the exit status and logout the shell on failure:
perl auth.pl; if [ $? -ne 0 ]; then exit; fi
Then in the Perl script:
if ( $attempts > $maxattempts ) {
die 'Authentication failed';
}
You would also need to stop the user skipping the authentication with ctrl+c or ctrl+z:
trap "echo no" SIGINT SIGTSTP
perl auth.pl; if [ $? -ne 0 ]; then exit; fi

How to emit a "beep" on my computer while running a script on a remote machine?

I run a long script on a remote machine and I would like to hear a beep when the script ends. On my machine I can add at the end of the script:
echo -e '\a' > /dev/console
but this is not working on the remote machine which complains :
-bash: /dev/console: Permission denied
How to achieve this ?
You could run the script by passing it as a parameter to ssh and then echo the beep locally:
ssh user#host /path/to/script; echo -e '\a' > /dev/console
Perhaps you might use /dev/tty instead of /dev/console. (I don't know how ssh handle beeps, so maybe you should start a terminal emulator, e.g. ssh -X -f remotehost xterm).

Loop until connected to SSH

Sometimes when connecting to a remote SSH server I get Connection Closed By *IP*; Couldn't read packet: Connection reset by peer. But after trying one or two more times it connects properly.
This presents a problem with a few bash scripts I use to automatically upload my archived backups to the SSH server, like so;
export SSHPASS=$sshpassword
sshpass -e sftp -oBatchMode=no -b - root#$sshaddress << !
cd $remotefolder
put $backupfolder/Qt_$date.sql.gz
bye
!
How can I have this part loop until it actually properly connects?
UPDATE: (Solution)
RETVAL=1
while [ $RETVAL -ne 0 ]
do
export SSHPASS=$sshpassword
sshpass -e sftp -oBatchMode=no -b - root#$sshaddress << !
cd $remotefolder
put $backupfolder/Qt_$date.tgz
bye
!
RETVAL=$?
[ $RETVAL -eq 0 ] && echo Success
[ $RETVAL -ne 0 ] && echo Failure
done
Try something like this :
export SSHPASS=$sshpassword
sshpassFunc() {
sshpass -e sftp -oBatchMode=no -b - root#$sshaddress << !
cd $remotefolder
put $backupfolder/Qt_$date.sql.gz
bye
!
}
until sshpassFunc; do
sleep 1
done
(not tested)
I am not a shell scripting expert, but I would check the return value of sshpass when it exits.
From man ssh:
ssh exits with the exit status of the remote command or
with 255 if an error occurred.
From man sshpath:
Return Values
As with any other program, sshpass returns 0 on success. In case of
failure, the following return codes are used:
Invalid command line argument
Conflicting arguments given
General runtime error
Unrecognized response from ssh (parse error)
Invalid/incorrect password
Host public key is unknown. sshpass exits without confirming the new key.
In addition, ssh might be complaining about a man in the middle
attack. This complaint does not go to the tty. In other words, even
with sshpass, the error message from ssh is printed to standard error.
In such a case ssh's return code is reported back. This is typically
an unimaginative (and non-informative) "255" for all error cases.
So try to run the command, and check its return value. If the return value was not 0 (for SUCCESS) then try again. Repeat using a while loop until you succeed.
Sidenote: why are you using sshpass instead of public-key (passwordless) authentication? It is more secure (you don't have to write down your password) and makes logging in via regular ssh as easy as ssh username#host.
There's even an easy tool to set it up: ssh-copy-id.

Resources