What is the cleanest way to ssh and run multiple commands in Bash?

前端 未结 12 2112
礼貌的吻别
礼貌的吻别 2020-11-22 09:14

I already have an ssh agent set up, and I can run commands on an external server in Bash script doing stuff like:

ssh blah_server "ls; pwd;"
         


        
相关标签:
12条回答
  • 2020-11-22 09:25

    This can also be done as follows. Put your commands in a script, let's name it commands-inc.sh

    #!/bin/bash
    ls some_folder
    ./someaction.sh
    pwd
    

    Save the file

    Now run it on the remote server.

    ssh user@remote 'bash -s' < /path/to/commands-inc.sh
    

    Never failed for me.

    0 讨论(0)
  • 2020-11-22 09:25

    SSH and Run Multiple Commands in Bash.

    Separate commands with semicolons within a string, passed to echo, all piped into the ssh command. For example:

    echo "df -k;uname -a" | ssh 192.168.79.134
    
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    Filesystem     1K-blocks    Used Available Use% Mounted on
    /dev/sda2       18274628 2546476  14799848  15% /
    tmpfs             183620      72    183548   1% /dev/shm
    /dev/sda1         297485   39074    243051  14% /boot
    Linux newserv 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
    
    0 讨论(0)
  • 2020-11-22 09:26

    Not sure if the cleanest for long commands but certainly the easiest:

    ssh user@host "cmd1; cmd2; cmd3"
    
    0 讨论(0)
  • 2020-11-22 09:28

    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.

    0 讨论(0)
  • 2020-11-22 09:31

    The easiest way to configure your system to use single ssh sessions by default with multiplexing.

    This can be done by creating a folder for the sockets:

    mkdir ~/.ssh/controlmasters
    

    And then adding the following to your .ssh configuration:

    Host *
        ControlMaster auto
        ControlPath ~/.ssh/controlmasters/%r@%h:%p.socket
        ControlMaster auto
        ControlPersist 10m
    

    Now, you do not need to modify any of your code. This allows multiple calls to ssh and scp without creating multiple sessions, which is useful when there needs to be more interaction between your local and remote machines.

    Thanks to @terminus's answer, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ and https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing.

    0 讨论(0)
  • 2020-11-22 09:33

    For anyone stumbling over here like me - I had success with escaping the semicolon and the newline:

    First step: the semicolon. This way, we do not break the ssh command:

    ssh <host> echo test\;ls
                        ^ backslash!
    

    Listed the remote hosts /home directory (logged in as root), whereas

    ssh <host> echo test;ls
                        ^ NO backslash
    

    listed the current working directory.

    Next step: breaking up the line:

                          v another backslash!
    ssh <host> echo test\;\
    ls
    

    This again listed the remote working directory - improved formatting:

    ssh <host>\
      echo test\;\
      ls
    

    If really nicer than here document or quotes around broken lines - well, not me to decide...

    (Using bash, Ubuntu 14.04 LTS.)

    0 讨论(0)
提交回复
热议问题