简体   繁体   中英

Running a Bash script over ssh

I'm trying to write a Bash script that will SSH into a machine and create a directory. The long-term goal is a bit more complicated, but for now I'm starting simple. However, as simple as it is, I can't quite seem to get it. Here's my code:

#!/bin/bash
ssh -T tunneluser@111.222.333.444 <<EOI

# Fix "TERM environment variable undefined" error.
TERM=dumb
export TERM

# Store todays date.
NOW=$(date +"%F")
echo $NOW

# Store backup path.
BACKUP="/backup/$NOW"
[ ! -d $BACKUP ] && mkdir -p ${BACKUP}
echo $BACKUP

exit
EOI

It runs without any explicit errors. However, the echoed $NOW and $BACKUP variables appear empty, and the /backup directory is not created. How do I fix this?

The shell on the local host is doing variable substitution on $NOW and $BACKUP because the "EOI" isn't escaped. Replace

 ssh tunneluser@111.222.333.444 <<EOI

with

 ssh tunneluser@111.222.333.444 <<\EOI

The variables are being evaluated in the script on the local machine. You need to subsitute the dollar signs with escaped dollar signs.

#!/bin/bash
ssh -T tunneluser@111.222.333.444 <<EOI

# Fix "TERM environment variable undefined" error.
TERM=dumb
export TERM

# Store todays date.
NOW=\$(date +"%F")
echo \$NOW

# Store backup path.
BACKUP="/backup/\$NOW"
[ ! -d \$BACKUP ] && mkdir -p \${BACKUP}
echo \$BACKUP

exit
EOI

Your script is doing substitution on the local host before being sent over.

Change your first line to:

ssh -T tunneluser@111.222.333.444 <<'EOI'

This will cause the raw script to get sent over and interpreted on your remote host.

If you wanted a mix (so for example, if you wanted the date command executed on your local host, you should leave ssh line unchanged and quote the individual command):

ssh -T tunneluser@111.222.333.444 <<EOI

# Execute the date command on the local machine.  The assignment still
# happens on the remote machine
NOW=$(date +"%F")

# Quote your $ so that the replacement happens on the remote machine
echo \$NOW

How to run a local script over SSH

Synopsis:

Script execution over SSH without copying script file. You need a simple SSH connexion and a local script.

Code:

#!/bin/sh
print_usage() {
        echo -e "`basename $0` ssh_connexion local_script"
        echo -e "Remote executes local_script on ssh server"
        echo -e "For convinient use, use ssh public key for remote connexion"
        exit 0
}

[ $# -eq "2" ] && [ $1 != "-h" ] && [ $1 != "--help" ] || print_usage

INTERPRETER=$(head -n 1 $2 | sed -e 's/#!//')

cat $2 | grep -v "#" | ssh -t $1 $INTERPRETER

Examples:

  • ssh-remote-exec root@server1 myLocalScript.sh #for Bash
  • ssh-remote-exec root@server1 myLocalScript.py #for Python
  • ssh-remote-exec root@server1 myLocalScript.pl #for Perl
  • ssh-remote-exec root@server1 myLocalScript.rb #for Ruby

Step by step explanations

This script performs this operations: 1° catches first line #! to get interpreter (ie: Perl, Python, Ruby, Bash interpreter), 2° starts remote interpeter over SSH, 3° send all the script body over SSH.

Local Script:

Local script must start with #!/path/to/interpreter - #!/bin/sh for Bash script - #!/usr/bin/perl for Perl script - #!/usr/bin/python for Python script - #!/usr/bin/ruby for Ruby script

This script is not based on local script extension but on #! information.

尝试:

NOW=`date +"%F"`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM