Shell script for ssh into a Unix/Linux server from MacOS X 10.10

10,289

Solution 1

I think you're just trying to copy files from the server behind NAT via gatewayserver.

I'd suggest you more simple solution.

  1. Set up password-less authentication (put private key from your desktop/Mac to both mentioned servers)
  2. Use something like

    ssh -MNf -L 60022:storageserver:22 username@gatewayserver
    

    to set up ssh tunnel via gatewayserver. Now your Mac's port 60002 has direct connection to port 22 of storageserver.

  3. At this point you may copy files directly via this tunnel:

    scp -P 60022 -R username@localhost:/path/to/folder .
    

Put these commands into your bash script and you will achieve what you want.

UPD:

Putting it all together, here's complete script:

#!/bin/bash

# set up tunnel
ssh -MNf -L 60022:storageserver:22 gatewayserver_username@gatewayserver || true

# copy files __directly__ into correct backup folder
scp -P 60022 -R "storageserver_username@localhost:/remote/path/to/retrievedfolder/at/storageserver" "/local/path/to/backup/retrievedfolder.`date +%Y%m%d`"

Prerequisites (run just one time on your Mac):

# Create SSH keys @ local machine
ssh-keygen

# Put your local SSH key to the gateway server
ssh-copy-id gatewayserver_username@gatewayserver

# Enable tunnel (will not ask your password if previous steps are correct)
ssh -MNf -L 60022:storageserver:22 gatewayserver_username@gatewayserver

# Put your local SSH key to the storageserver server
ssh-copy-id -p 60022 storageserver_username@localhost

Solution 2

If you look at Shell Script for logging into a ssh server you'll notice that the shebang line is

#!/usr/bin/expect

This is an expect script, not a bash script. You'll need to install Expect if you don't already have it.

Share:
10,289

Related videos on Youtube

Charles Butler
Author by

Charles Butler

Updated on September 18, 2022

Comments

  • Charles Butler
    Charles Butler almost 2 years

    I am attempting to ssh into a server by using a bash script from MacOSX.

    #!/bin/bash
    
    spawn ssh username@gatewayserver
    expect "password"
    send "Mypassword\r"
    interact
    
    spawn ssh username@storageserver
    expect "password"
    send "Mypassword\r"
    interact
    cd /path
    
    spawn scp -r retrievedfolder username@gatewayserver:/path/
    expect "password"
    send "Mypassword\r"
    interact
    
    exit
    exit
    
    spawn scp -r username@gatewayserver:/path/retrievedfolder .
    expect "password"
    send "Mypassword\r"
    interact
    
    spawn ssh username@gatewayserver
    expect "password"
    send "Mypassword\r"
    interact
    rm -r retrievedfolder/
    exit
    
    mv -nv -- "$retrievedfolder" "$retrievedfolder.$(date +%Y%m%d)"
    mv /retrievedfolder /backup
    

    If you can follow the probably redundant code, the goal was to log into the gateway server to get to the storage server. cd to the appropriate folder. secure copy the folder i want to a directory on the gateway server, and then copy the file from the gateway server to the desktop. Then I want to remove the retrieved folder from the gateway server (storage limitations) and move the copied folder to a folder on the desktop with the current date appended to the end of the file name. I think that most of what I have written should work if I were running linux but bash on MacOS isn't recognizing spawn send or interact and it is looking for a file or directory after expect.

    After some help from Stephen Kitt and webKnjaZ, my code looks more like this:

    #!/bin/bash
    
    ssh username@gatewayserver 'ssh username@storageserver; cd /path/; scp -r retrievedfolder username@gatewayserver:/path/'
    
    scp -r username@gatewayserver:/path/retrievedfolder .
    
    ssh username@gatewayserver 'rm -r retrievedfolder/'
    
    mv -nv -- "retrievedfolder" "retrievedfolder.$(date +%Y%m%d)"
    mv retrievedfolder.$(date +%Y%m%d)/ backup/
    

    After correctly setting up passwordless SSH it almost works correctly. Without ssh -tt it gives me an error message: "Pseudo-terminal will not be allocated because stdin is not a terminal". With ssh -tt it stops at the command prompt once logged into the second server, and when I use ssh -T it hangs. (probably in the same spot, but just not visible)

    • webknjaz
      webknjaz over 9 years
      that's expected behavior. when you try to run 'ssh under ssh' the remote one doesn't get access to your TTY. But the point is to avoid binding to TTY. See my answer updated.
  • Charles Butler
    Charles Butler over 9 years
    Fantastic! I did not catch that. I suppose I should search some more on how to do it in bash then.
  • Stephen Kitt
    Stephen Kitt over 9 years
    Why not just try Expect? It may even already be installed on your Mac...
  • Charles Butler
    Charles Butler over 9 years
    Stephen, expect is installed. I am attempting to write it in bash because I already know at least rudimentary bash scripting and would rather get better at one language than learn the basics of another.
  • muru
    muru over 9 years
    @CharlesButler If you don't have password-less authentication set up, trying to enter passwords will lead you to expect sooner or later.
  • Charles Butler
    Charles Butler over 9 years
    @muru After a bit of searching I haven't found an easy way of doing what I want solely in bash. Now I am attempting to call expect within the bash script
  • Klaatu von Schlacker
    Klaatu von Schlacker over 9 years
    In addition to this, you might consider using ssh keys so that you are not constantly required to enter your password manually. Then the only thing your script would need to wait on is the completion of the copy action.
  • webknjaz
    webknjaz over 9 years
    Klaatu von Schlacker, that's exactly what I meant :)
  • webknjaz
    webknjaz over 9 years
    Charles Butler, there's no need to run scp on remote machine. All commands I wrote are meant to be ran from localhost
  • webknjaz
    webknjaz over 9 years
    I've updated my answer, hope it became more clear.