How to start interactive ssh terminal from bash script?
The problem is that you give ssh
input from your cat $HOSTS_FILE
command instead of from your keyboard. That's why you can't interact with it.
The easiest, ugliest fix is to redirect from the current tty:
ssh -t -l $username $hostname < /dev/tty
Interactive ssh session started from bash command
Input to xargs
(and therefore bash
and therefore ssh
) is coming from the pipe, not your terminal. Depending on the larger context, one of these options should work to let ssh
read from the terminal:
Capture the list of hosts to an array first, then use a
for
loop instead ofxargs
. Something like this:readarray -t hostarray < <(echo "username@host")
for host in "${hostarray[@]}"; do
ssh "$host"
doneAdd the
-o
option toxargs
, which tells it to redirect stdin of the command from /dev/tty (i.e. the terminal).Redirect the regular stdin around the
xargs
command via a different file descriptor, e.g. #3 (note: I haven't tested this):{ echo "username@host" | xargs -I{} bash -x -c 'ssh -ttt "$0" <&3' {}; } 3<&0
BTW, in addition to problems with ssh
not getting input it's supposed to get (i.e. from the terminal), you can also have trouble with it stealing input that was intended for something else, like parts of the list of hosts you wanted xargs
to read. See BashFAQ #89: I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!
Open interactive SSH session from Node script
You can use the ssh2-client package
const ssh = require('ssh2-client');
const HOST = 'junk@localhost';
// Exec commands on remote host over ssh
ssh
.exec(HOST, 'touch junk')
.then(() => ssh.exec(HOST, 'ls -l junk'))
.then((output) => {
const { out, error } = output;
console.log(out);
console.error(error);
})
.catch(err => console.error(err));
// Setup a live shell on remote host
ssh
.shell(HOST)
.then(() => console.log('Done'))
.catch(err => console.error(err));
DISCLAIMER : I'm the author of this module
Interactive SSH session using Net::SSH or creating a STDIN Socket
Sockets are really nothing more than file descriptors, and since STDIN is a file descriptor too, it doesn't hurt to try.
What you want however, is to put the TTY into raw mode first to get interactivity.
This code seems to work fine:
begin
system('stty cbreak -echo')
Net::SSH.start(...) do |session|
session.open_channel do |...|
...
session.listen_to(STDIN) { |stdin|
input = stdin.readpartial(1024)
channel.send_data(input) unless input.empty?
}
end.wait
end
ensure
system('stty sane')
end
how to interact with Paramiko's interactive shell session?
I imported a file, interactive.py, found on Paramiko's GitHub. After importing it, I just had to change my code to this:
try:
import interactive
except ImportError:
from . import interactive
...
...
channel.invoke_shell()
interactive.interactive_shell(channel)
sshClient.close()
Related Topics
Access Attributes/Methods Comments Programmatically in Ruby
Can't Install Ruby via Rvm, Error Running '_Rvm_Make -J4' on Ubuntu 22.04
Rails Cancan and State MAChine - Authorizing States
How to Get Today's Date in Ruby 1.9.3
Exclude Option from Collection.Map in Ruby on Rails
Ruby Strftime '%Z' Method Returns '0545' Instead of 'Npt'
Testing Rake Tasks with Rspec Is Not Accepting Arguments
Ruby: Why Does '#Hash' Need to Overridden Whenever '#Eql' Is Overridden
Mongodb Group Using Ruby Driver
Creating a Gmail Draft with Recipients Through Gmail API
Rails Error Message Displays Key and I Only Want Value
Rails 7 Signup Form Doesn't Show Error Messages
How to Include Ё in [А-Я] Regexp Char Interval
Webmock Simulate Failing API (No Internet, Timeout ++)
How to Convert a Ruby Bigdecimal to a 2-Decimal Place String
Does It Matter If a Conditional Statement Comes Before or After the Expression
Undefined Method 'Require_Relative' for Main:Object (Nomethoderror)