How can i execute 2 or more commands in the same ssh session?
see if there's something analogous to the file(utils?) cd block syntax, otherwise just run the command in the same subshell, e.g. ssh.exec "cd /var/example/engines/; pwd" ?
Run Multiple Commands on Same SSH Session in Bash?
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.
What is the cleanest way to ssh and run multiple commands in Bash?
How about a Bash Here Document:
ssh otherhost << EOF
ls some_folder;
./someaction.sh 'some params'
pwd
./some_other_action 'other params'
EOF
To avoid the problems mentioned by @Globalz in the comments, you may be able to (depending what you're doing on the remote site) get away with replacing the first line with
ssh otherhost /bin/bash << EOF
Note that you can do variable substitution in the Here document, but you may have to deal with quoting issues. For instance, if you quote the "limit string" (ie. EOF
in the above), then you can't do variable substitutions. But without quoting the limit string, variables are substituted. For example, if you have defined $NAME
above in your shell script, you could do
ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF
and it would create a file on the destination otherhost
with the name of whatever you'd assigned to $NAME
. Other rules about shell script quoting also apply, but are too complicated to go into here.
Running multiple commands in one SSH session
Thanks to @JimB I am now doing this instead:
// Create a single command that is semicolon seperated
commands := []string{
"docker login",
"docker ps",
}
command := strings.Join(commands, "; ")
And then running it the same as before:
if err := session.Run(command); err != nil {
panic("Failed to run command: " + command + "\nBecause: " + err.Error())
}
fmt.Println(output.String())
Related Topics
What's Wrong with the Square and Rectangle Inheritance
Controller Monkey Patch in Initializer Gets Lost When Rails Reloads Classes
Scraping a Site That Requires Login Username and Password on Two Separate Pages
The Program 'Rails' Is Currently Not Installed
How to Get a Listing of Only Files Using Dir.Glob
Exclude Option from Collection.Map in Ruby on Rails
How to Install Libksba on MAC Osx
Actioncontroller::Routingerror (No Route Matches [Get] "/"):
Rvm Install Ruby-1.9.3-P286: Error Running 'Make -J 9' (Osx: Mountain Lion)
Issues with Installing Ruby 2.0.0 on MACos Catalina
Ruby How to Merge Two CSV Files with Slightly Different Headers
Why Can't I Create an Array as a Column in a Table in Rails
Rails 3 and PDFkit. How to Specify Page Size
How to Parse Xml Nodes to CSV with Ruby and Nokogiri
How to Mock Super in Ruby Using Rspec
How to Convert a Ruby Bigdecimal to a 2-Decimal Place String