前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[附录代码] shell脚本一步完成多层ssh跳转时的文件传输

[附录代码] shell脚本一步完成多层ssh跳转时的文件传输

作者头像
PedroQin
发布2020-05-12 10:41:59
5480
发布2020-05-12 10:41:59
举报
文章被收录于专栏:WriteSimpleDemoWriteSimpleDemo

transfer_file.sh

代码语言:javascript
复制
#!/usr/bin/expect
###############################################
# Author      :   PedroQin
# Date        :   2020-04-26 20:26:20
# Description :
# Version     :   1.0.0
###############################################


set timeout         -1
set script_name     $argv0
# send or recive file
set send_receive    [lindex $argv 0]
set dir_name        [lindex $argv 1]
set file_name       [lindex $argv 2]
set server_offset   [lindex $argv 3]
set server_id       [lindex $argv 4]
set username        [lindex $argv 5]
set host            [lindex $argv 6]
set passwd          [lindex $argv 7]
set hostname        [lindex $argv 8]
set remain_argv     [lrange $argv 9 999]

set basename        [lindex [split "$file_name" "/"] end]
set server_offset   [expr $server_offset + 1]

if {$send_receive=="send"} {
    # send file

    if {$remain_argv!=""} {
        send_user "$server_offset. scp to $server_id $host ##**==++==**## ==> "
        if {$server_offset=="1"} {
            spawn scp -r $file_name $username@$host:$dir_name/
        } else {
            spawn scp -r $dir_name/$basename $username@$host:$dir_name/
        }
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "password:"             { send "$passwd\n" ; exp_continue}
        }

        send_user "$server_offset. ssh to $server_id $host ##**==++==**## ==> "
        spawn ssh $username@$host
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "$host's password:"     { send "$passwd\n" ; exp_continue}
            "$hostname*#"           { send "$script_name $send_receive $dir_name $file_name $server_offset $remain_argv && wait && sync && exit\n" ; exp_continue}
        }
        
    } else {

        send_user "$server_offset. scp to $server_id $host ##**==++==**## ==> "
        spawn scp -r $dir_name/$basename $username@$host:$dir_name/
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "password:"             { send "$passwd\n" ; exp_continue}
        }

    }
} else {
    # recive file
    spawn mkdir -p $dir_name
    if {$remain_argv!=""} {
    
        send_user "$server_offset. ssh to $server_id $host ##**==++==**## ==> "
        spawn ssh $username@$host
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "$host's password:"     { send "$passwd\n" ; exp_continue}
            "$hostname*#"           { send "$script_name $send_receive $dir_name $file_name $server_offset $remain_argv && wait && sync && exit\n" ; exp_continue}
        }
        
        send_user "$server_offset. scp from $server_id $host ##**==++==**## ==> "
        spawn scp -r $username@$host:$dir_name/$basename $dir_name/
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "$host's password:"     { send "$passwd\n" ; exp_continue}
        }
    } else {
        send_user "$server_offset. scp from $server_id $host ##**==++==**## ==> "
        spawn scp -r $username@$host:$file_name $dir_name/
        expect {
            "yes/no"                { send "yes\n"; exp_continue}
            "password:"             { send "$passwd\n" ; exp_continue}
        }
    }
}
#interact
#expect eof

multi_scp.sh

代码语言:javascript
复制
#!/bin/bash
###############################################
# Author      :   PedroQin
# Date        :   2020-04-26 22:43:32
# Description :
# Version     :   1.0.0
###############################################


config_file="/etc/multi_scp_conf.xml"
parameters=""
# the file is not in $dir
not_dir=0
# show message in green
function green_message()
{
    tput bold
    echo -ne "\033[32m$@\033[0m"
    tput sgr0
    echo
}

# show message in red
function red_message()
{
    tput bold
    echo -ne "\033[31m$@\033[0m"
    tput sgr0
    echo
}

function isdigit()
{
    local str=
    for str in $@
    do
        str=$1
        while [ -n "$str" ]; do
            echo ${str:0:1} | grep "[-.0-9]" > /dev/null 2>&1
            [ $? -ne 0 ] && return 27
            str=`echo ${str:1}`
        done
        shift
    done
    return 0
}

# $1 - keyword
# $2 - path to xml file
function xml_parse()
{
    local keyword=""
    local line=""
    local col=`sed -n "/<$1\>/=" $2`
    local last=`sed -n "/<\/$1>/=" $2`

    [ -z "$col" ] && echo "err=255" && return 255

    line=`sed -n "$col p" $2`
    line=${line#*$1}

    if [ -z "$last" ]; then
        line=${line%/>*}
        echo ${line} | awk '{for (c=1;c<=NF;c++) print $c}'
        last=0
    else
        echo ${line%*>}
    fi

    let col+=1
    while (( $col < $last )); do
        line=`sed -n "$col p" $2`
        if [ -n "$line" ]; then
            keyword=${line##*/}
            line=${line%<*}
            echo "${keyword/>/=}\"${line#*>}\""
        fi
        let col+=1
    done
    return 0
}

# decode the cmd
function parse_cmd()
{
    # decode the config
    route=`xml_parse "to_server_${server_id}" $config_file`
    if [ -z "$route" ] ;then
        red_message "Can't find route info in $config_file !"
        usage
    fi
    # get script and dir
    eval `xml_parse common $config_file`
    if [ -z "$command" ] || [ -z "$dir" ] ;then
        red_message "common information(command and dir) in $config_file is not complete !"
    fi
    # this 0 using for transfer_file.sh to calculate how many floors now
    parameters="$command $method $dir $file_name 0"
    offset=0
    for i in `echo "$route"|tr '>' ' '`;do
        # skip the local server
        [ $offset -eq 0 ] && let offset+=1 && continue

        eval `xml_parse server.$i $config_file`
        if [ -z "$username" ] || [ -z "$IP" ] || [ -z "$passwd" ] ;then
            red_message "server.$i information in $config_file is not complete !"
            exit 254
        fi
        
        parameters="$parameters ID.$i $username $IP $passwd $hostname"
    done
    echo "$parameters"
    $parameters

}

function usage()
{
    cat <<USAGE
    $0 -t <server id in $config_file> -f <file name to send/receive> -m <send or receive> [ -c <config_file> ]
    $0 -h
USAGE
    exit 255
}

while getopts ":t:hc:f:m:" optname ;do
    case "$optname" in
        "m")
        method="$OPTARG"
        method=`echo "$method"|tr 'A-Z' 'a-z'`
        if [ "$method" == "send" -o "$method" == "s" ] ;then
            method="send"
        elif [ "$method" == "receive" -o "$method" == "r" ];then
            method="receive"
        else
            red_message "transfer method must be send/receive !"
            usage
        fi
        ;;

        "t")
        server_id="$OPTARG"
        if ! isdigit "$server_id" ;then
            red_message "server_idi: $server_id is illegal !"
            usage
        fi
        ;;

        "c")
        config_file="$OPTARG"
        ;;

        "f")
        file_name="$OPTARG"
        ;;

        "h")
        usage
        ;;
    esac
done
if [ -z "$method" ] || [ -z "$server_id" ] ||[ -z "$file_name" ] ;then
    usage
fi
if [ ! -f "$config_file" ];then
    red_message "Can't locate config file $config_file"
    exit 253
fi
parse_cmd

multi_scp_conf.xml

代码语言:javascript
复制
<route>
    <to_server_2 1 > 2 />
    <to_server_3 1 > 2 > 3 />
    <to_server_4 1 > 2 > 3 > 4 />
    <to_server_5 1 > 2 > 3 > 4 > 5 />
    <to_server_6 1 > 2 > 3 > 4 > 6 />
</route>
<common>
    <command>transfer_file</command>
    <dir>/tmp</dir>
</common>
<server_info>
    <server.1 item="local server">
        <username>root</username>
        <IP>192.168.0.1</IP>
        <passwd>123456</passwd>
        <hostname>local</hostname>
    </server.1>
    <server.2 item="server 1">
        <username>root</username>
        <IP>192.168.1.1</IP>
        <passwd>123456</passwd>
        <hostname>server1</hostname>
    </server.2>
    <server.3 item="server 2">
        <username>root</username>
        <IP>192.168.2.1</IP>
        <passwd>123456</passwd>
        <hostname>server2</hostname>
    </server.3>
    <server.4 item="server 3">
        <username>root</username>
        <IP>192.168.3.1</IP>
        <passwd>123456</passwd>
        <hostname>server3</hostname>
    </server.4>
    <server.5 item="server 4">
        <username>root</username>
        <IP>192.168.4.1</IP>
        <passwd>123456</passwd>
        <hostname>server4</hostname>
    </server.5>
    <server.6 item="server 5">
        <username>root</username>
        <IP>192.168.5.1</IP>
        <passwd>123456</passwd>
        <hostname>server5</hostname>
    </server.6>
</server_info>

install.sh

代码语言:javascript
复制
#!/bin/bash
###############################################
# Author      :   PedroQin
# Date        :   2020-04-28 15:40:50
# Description :
# Version     :   1.0.0
###############################################

Lines=66
MD5="e83f8ab79a1f0df0ef695030d6957066"
# show message in green
function green_message()
{
    tput bold
    echo -ne "\033[32m$@\033[0m"
    tput sgr0
    echo
}

# show message in red
function red_message()
{
    tput bold
    echo -ne "\033[31m$@\033[0m"
    tput sgr0
    echo
}

# print description and then run it
function print_run()
{
    if [ $# -eq 1 ];then
        green_message "$1"
        eval "$1"
    elif [ $# -eq 2 ];then
        green_message "$1"
        eval "$2"
    else
        return 1
    fi
}

function install_fail()
{
    red_message "install fail"
    exit 255
}

cat $0 |tail -n +$Lines > /tmp/multi_scp.tgz
md5_cur=`md5sum /tmp/multi_scp.tgz | awk '{print $1}'`
if [ "$md5_cur" != "$MD5" ];then
    red_message "Wrong md5sum ..."
    exit 255
else
    green_message "md5sum check pass"
fi
print_run "tar -xf /tmp/multi_scp.tgz -C /tmp"
print_run "cp /tmp/multi_scp/transfer_file.sh /usr/bin/transfer_file"   || install_fail
print_run "(cd /usr/bin; chmod +x transfer_file)"
print_run "cp /tmp/multi_scp/multi_scp.sh /usr/bin/multi_scp"           || install_fail
print_run "(cd /usr/bin; chmod +x multi_scp)"
print_run "cp /tmp/multi_scp/multi_scp_conf.xml /etc"                   || install_fail
print_run "rm -rf /tmp/multi_scp*"
echo Done
exit
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WriteSimpleDemo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • transfer_file.sh
  • multi_scp.sh
  • multi_scp_conf.xml
  • install.sh
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档