zoukankan      html  css  js  c++  java
  • scp 上传文件到多个服务器节点

    参考:scp批量上传文件到多台机器上(升级版)

    实测,代码可运行.

    1.如果遇到syntax error near unexpected token问题,基本是由于windows环境下编写的shell脚本上传到UNIX中包含了^M引起的。

    使用remove_ctrlM.sh替换掉sh脚本中的^M字符,也可以使用 vi -b your_file编辑文件。

    如果scp.conf报syntax error near unexpected token问题,则vi -b scp.conf编辑此配置文件,替换掉其中的特殊字符。

    2.如果遇到source: not found的异常,查看ubuntu12.04中shell脚本无法使用source的原因及解决方法


    原作者的脚本在copy dir的时候,会将整个dir目录拷贝至 target中,这跟scp命令本身有关。

    scp -r ./code/oaf/* huanghongbo@192.168.233.136:$JAVA_TOP会仅拷贝oaf目录下的文件及文件夹至$JAVA_TOP

    但是此处不能用sh multi_scp.sh ./scp.conf ./code/oaf/* $JAVA_TOP,会抛出异常。

    所以我针对想仅拷贝目录下的文件及文件夹做了一点改动。

    把multi_scp.sh中的

    /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file" "$scp_target" 

    改为了

    if [ -d "$scp_file" ]
    then
    for f in ` ls "$scp_file"`
    do
    /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file/$f" "$scp_target"
    done
    else
    #scp file or dir  
    /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file" "$scp_target"
    fi

    version2,拷贝目录至target.

    version3,仅拷贝目录下的内容至target.


    鉴于此种方式需要使用linux的expect模块,我又写了一个简陋的scp,此种方式需要在每次执行scp的时候交互式的输入scp的密码,但是特别繁琐,所以就想到了加入ssh信任免密码登录。

    Step 1. Linux基础 - scp免密码登陆进行远程文件同步

    Step 2. $ sh scp2multi_nodes.sh(下载)

    #!/bin/bash
    ssh_hosts=("192.168.233.136" "192.168.233.137")
     
    default_ssh_user="huanghongbo" 
    default_ssh_password="huanghongbo"
    default_ssh_port="22"
     
    port=$default_ssh_port
    scp_file=./code/oaf/
    target=$JAVA_TOP
    scpuser=$default_ssh_user
     
    for((i=0;i<${#ssh_hosts[@]};i++))  
    do
    #remote ssh host  
    scphost=${ssh_hosts[$i]}
    echo $i node ,host is $scphost
    #echo "["`date +"%F %T"`"] (scp -r $scp_file $ssh_user@$ssh_host:$ssh_port:$scp_target) start" 
     
    echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target  ) start"
    #scp -q -r -P $port $scp_file/* $scpuser@$scphost:$target
    #-q 不显示传输进度
     
    scp -r -P $port $scp_file/* $scpuser@$scphost:$target
     
    if [ "$?" -eq "0" ]  
    then 
    success_hosts="$success_hosts,$scphost" 
    else 
    fail_hosts="$fail_hosts,$scphost" 
    fi 
     
    echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target  ) end"    
     
    done  
    echo "success_hosts=[$success_hosts]" 
    echo "fail_hosts=[$fail_hosts]" 

    PS:

    1.示例中的target都是使用的环境变量$JAVA_TOP,如果remote环境和local环境的$JAVA_TOP环境变量不一致,则会导致传输到错误的路径或者scp:***:No such file or directory。

    在scp中如何获取remote环境的环境变量,我暂时还没找到方法。

    看到的一种比较合理的解释是

    How is it supposed to know what the remote variables values are? scp/rcp DO NOT execute a .profile or any login script. They establish a connection to the remote server only.

    2.Expect在这个程序里就是用来帮助自动输入scp的密码,Expect主要用于把需要人工交互的程序变为程序自动化完成,这个对于运维批量部署系统,批量无人值守安装,批量执行命令,批量上传下载
     现代的Shell对程序提供了最小限度的控制(开始,停止,等等),而把交互的特性留给了用户。 这意味着有些程序,你不能非交互的运行,比如说passwd。 有一些程序可以非交互的运行,但在很大程度上丧失了灵活性,比如说fsck。这表明Unix的工具构造逻辑开始出现问题。Expect恰恰填补了其中的一些裂痕,解决了在Unix环境中长期存在着的一些问题。

    default_ssh_user="huanghongbo" 
    default_ssh_password="huanghongbo"
    default_ssh_port="22"
     
    port=$default_ssh_port
    scp_file=./code/oaf/
    target=$JAVA_TOP
    scpuser=$default_ssh_user
     
    for((i=0;i<${#ssh_hosts[@]};i++))  
    do
    #remote ssh host  
    scphost=${ssh_hosts[$i]}
    echo $i node ,host is $scphost
    #echo "["`date +"%F %T"`"] (scp -r $scp_file $ssh_user@$ssh_host:$ssh_port:$scp_target) start" 
     
    echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target  ) start"
    #scp -q -r -P $port $scp_file/* $scpuser@$scphost:$target
    #-q 不显示传输进度
     
    scp -r -P $port $scp_file/* $scpuser@$scphost:$target
     
    if "$?" -eq "0" ]  
    then 
    success_hosts="$success_hosts,$scphost" 
    else 
    fail_hosts="$fail_hosts,$scphost" 
    fi 
     
    echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target  ) end"    
     
    done  
    echo "success_hosts=[$success_hosts]" 
    echo "fail_hosts=[$fail_hosts]" 
  • 相关阅读:

    暴力求解/数学问题
    Leetcode207. Course Schedule
    Balanced Team
    由先序和中序求后序
    Median String
    树的同构
    uva 202
    整除光棍
    阅览室
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/6255582.html
Copyright © 2011-2022 走看看