SSH the output to different terminals [duplicate] - linux

This question already has answers here:
how do i start commands in new terminals in BASH script
(2 answers)
Closed 17 days ago.
I am using for loop to SSH multiple hosts
#!/usr/bin/bash
bandit=$(cat /root/Desktop/bandit.txt)
for host in {1..2}
do
echo "inside the loop"
ssh bandit$host#$bandit -p 2220
echo "After the loop"
done
#ssh bandit0#bandit.labs.overthewire.org -p 2220
bandit.txt has the following content " bandit.labs.overthewire.org"
I am getting the SSH prompt but one at a time, say for example First I got "bandit1" host login prompt, and after closing the "bandit1" ssh host I am getting second ssh session for "bandit1"
I would like to get two different terminals for each SSH session.

But there is no such things as "terminal window" in bash (well, there is a tty, yours; but I mean, you can't just open a new window. Bash is not aware that it is running inside a specific program that emulate the behavior of a terminal in a GUI window).
So it can't be as easy as you would think.
Of course, you can choose a terminal emulator, and run it yourself.
For example
for host is {1..2}
do
xterm -e ssh bandit$host#$bandit -p 2220 &
done
maybe what you are looking for, if you have xterm program installed.

Maybe with some additional error checking, something like this -
scr=( /dev/stdout
$(ps -fu $USERNAME |
awk '$4~/^pty/{lst[$4]} END{for (pty in lst) print pty}' ) )
for host in {1..2}; do echo ssh bandit$host#etc... >> /dev/${scr[$host]}; done
There are a lot of variations and kinks to work out though. tty or pty? what is there's no other window open? etc... But with luck it will give you something to work from.

Related

Using SSH with expected user input for picking an environment on the server

I am working on a script in linux in which i need to SSH to another server.
I am using this syntax ssh user#ip
When doing a manual SSH when we type "ssh user#ip" a few second, a second prompt will show and ask what environment are we choosing ex 1 to 4
(4) - this is the number of the environment i will be choosing.
But when doing ssh user#ip 4 - error received (bash command not found)
Here is the image on what is the prompt when using ssh
Without knowing what happens after you select the environment, its probably something like:
echo 4 | ssh user#ip
Feed 4 to whatever is prompting for environment, then exit.
If you need to stay connected, then something like
echo 4 | ssh -tt user#ip "ksh -l"
ksh -l could be replaced by some other shell or command like vi foo.txt (here when the command exits, the connection closes).
The above is similar to this previous question:
Run ssh and immediately execute command

How to get the output of a telnet command from bash?

I'm trying to get the list of processes running on my Windows machine from Linux, but I don't get any output when I do it in a script. If I use telnet manually and use the command pslist I get the complete list of processes, but not in my script.
Here is the bash script (minus the variables):
( echo open ${host}
sleep 1
echo ${user}
sleep 3
echo ${pass}
sleep 1
echo pslist
sleep 2
) | telnet
and I simply call it with bash pslist.sh and the output is something like that:
telnet> Trying ip_address...
Connected to ip_address.
Escape character is '^]'.
Welcome to Microsoft Telnet Service
login: my_loginmy_passwordpslistConnection closed by foreign host.
What am I doing wrong ?
telnet is notoriously tricky to script. You may be able to succeed more often if you add a longer still sleep between the commands.
A better approach is to switch to a properly scriptable client, viz. netcat (aka nc). Better still would be to install an SSH server on your Windows box (perhaps for security only make it accessible from inside your network) and set it up with passwordless authentication. Then you can simply ssh user#ipaddress pslist
Terminate each echo with \r character, like this: echo -e "${user}\r"

Run Multiple Commands on Same SSH Session in Bash? [duplicate]

This question already has answers here:
What is the cleanest way to ssh and run multiple commands in Bash?
(14 answers)
Closed 3 years ago.
I would like to run several commands on one SSH session. For example, my script right now has something like the following:
ssh "machine A" do-thing-1
ssh "machine B" do-thing-2
ssh "machine A" do-thing-3
Having to SSH to A again in the third line is wasting a lot of time. How do I execute this without having to SSH again? Is this possible?
If the ssh to A does not consume its standard input, you can easily make it wait for input. Perhaps something like this.
ssh B 'sleep 5; do-thing-2; echo done.' | ssh A 'do-thing-1; read done; do-thing3'
The arbitrary sleep to allow do-thing-1 to happen first is obviously a wart and a potential race condition.
A somewhat simpler and more robust solution is to use the ControlMaster feature to create a reusable ssh session instead.
cm=/tmp/cm-$UID-$RANDOM$RANDOM$RANDOM
ssh -M -S "$cm" -N A &
session=$!
ssh -S "$cm" A do-thing-1
ssh B do-thing-2
ssh -S "$cm" A do-thing-3
kill "$session"
wait "$session"
See https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing for more.
You can use screen
$: screen
$: do-thing-1
Ctrl-A and Ctrl-D exit this screen,
$: screen
$: do-thing-2
Ctrl-A and Ctrl-D exit this screen,
$: screen
$: do-thing-2
Ctrl-A and Ctrl-D exit this screen,
view all `screen`,
$: screen -ls
Restore screen by id,
$: screen -r <Screen ID>

Background process which has no IO can be affected by keybord input?

when I type this command in shell
ssh 127.0.0.1 "sleep 10"&
I click “Enter” on keyboard continuely,and this process will be stopped like this:
[4]+ Stopped ssh 127.0.0.1 "sleep 10"
if I do not click the "enter" it will be done
why?
See the man page:
-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A common trick is
to use this to run X11 programs on a remote machine. For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and
the X11 connection will be automatically forwarded over an encrypted channel. The ssh program will be put in the background. (This does not
work if ssh needs to ask for a password or passphrase; see also the -f option.)
On my system, even without the keyboard input, it stops:
$ ssh 127.0.0.1 "sleep 10" &
[1] 14986
$ jobs
[1]+ Stopped ssh 127.0.0.1 "sleep 10"
However, the following continues to run:
$ ssh 127.0.0.1 "sleep 10" </dev/null &
[1] 15580
$ jobs
[1]+ Running ssh 127.0.0.1 "sleep 10" < /dev/null &
Apparently ssh is looking for input and, as background process, can't get it. Redirecting stdin from /dev/null tells it not to bother, and it continues running even in background.
Update: This above matches what #BraveNewCurrency found in the documentation: to make ssh run in the background, input must be redirected from /dev/null, and ssh provides an option -n that, effectively, does just that.

SSH: guarding stdout against disconnect

My server deployment script triggers a long-running process through SSH, like so:
ssh host 'install.sh'
Since my internet connection at home is not the best, I can sometimes be disconnected while the install.sh is running. (This is easily simulated by closing the terminal window.) I would really like for the install.sh script to keep running in those cases, so that I don't end up with interrupted apt-get processes and similar nuisances.
The reason why install.sh gets killed seems to be that stdout and stderr are closed when the SSH session is yanked, so writing to them fails. (It's not an issue of SIGHUP, by the way -- using nohup makes no difference.) If I put touch ~/1 && echo this fails && touch ~/2 into install.sh, only ~/1 is created.
So running ssh host 'install.sh &> install.out' solves the problem, but then I lose any "live" progress and error output.
So my question is: What's an easy/idiomatic way to run a process through SSH so that it doesn't crash if SSH dies, but so that I can still see the output as it runs?
Solutions I have tried:
When I run things manually, I use screen for cases like this, but I don't think it will be of much help here because I need to run install.sh automatically from a shell script. Screen seems to be made for interactive use (it complains "Must be connected to a terminal.").
Using install.sh 2>&1 | tee install.out didn't help either (silly of me to think it might).
You can redirect stdout/stderr into install.out and then tail -f it. The following snippet actually works:
touch install.out && # so tail does not bark (race condition)
(install.sh < /dev/null &> install.out &
tail --pid "$!" -F install.out)
But surely there must a less awkward way to do the same thing?
Try using screen:
screen ./install.sh
If your ssh session gets interrupted, you can simply reattach to the session via another ssh connection:
screen -x
You can provide a terminal to your ssh session using the -t switch:
ssh -t server screen ./install.sh
install.sh 2>&1 | tee install.out
if the only issue is not getting stderr. You didn't say exactly why the tee wasn't acceptable. You may need the other nohup/stdin tweaks.

Resources