参考: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="" port=$default_ssh_port
scp_file=./code/oaf/
target=$JAVA_TOP
scpuser=$default_ssh_user for((i=;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 "" ]
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]" 

scp 上传文件到多个服务器节点的更多相关文章

  1. c++使用http协议上传文件到七牛云服务器

    使用c++ http协议上传文件到七牛服务器时,比较搞的一点就是header的设置: "Content-Type:multipart/form-data;boundary=xxx" ...

  2. linux 执行远程linux上的shell脚本或者命令以及scp 上传文件到ftp--免密码登陆

    场景:在linux A 上执行Linux B上的shell脚本和命令 步骤1.设置ssh免登陆 1.SSH无密码登录 # 本地服务器执行(A机器):生成密钥对 ssh-keygen -t dsa -P ...

  3. scp 上传文件自动录入密码

    --- 服务器IP地址 des_host=serverIp 服务器存储路径(文件上传后存储指定目录下) des_direc=/home/lk/ 服务器用户密码 des_pass=root_passwo ...

  4. linux scp上传文件到其他机器上

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  5. springboot +fastdfs 上传文件到到云服务器

    fastdfs在云服务器的搭建和配置:https://blog.csdn.net/qq_41592652/article/details/104006289 springboot结构如下: appli ...

  6. PHP 利用CURL(HTTP)实现服务器上传文件至另一服务器

    // 上传端 /** * 向目标地址推送xls文件 * @Date 2019/4/29 */ public function putXls() { // 目标接口 $url = "http: ...

  7. scp上传文件到远程服务器

    scp -P 22 E:/download/2028792_www.yeves.cn_nginx/cloud.pem root@ip:/usr/local/src

  8. windows上传文件到linux云服务器上

    安装putty,将pscp.exe移到 C:\Windows\System32 目录下. 在cmd 中执行,pscp -l rot -pw [password] -ls [ip]:/opt 查看目录 ...

  9. ssh 上传文件以及文件夹到linux服务器

    闲来无事分享一篇,帮助到你的话,麻烦给老弟点个关注.经常会分享一些实用技能. 回归正题,现在服务器linux很多.是不是不会传文件?别急 下面就是方法: 一.上传文件到linux服务器 首先从你本地切 ...

随机推荐

  1. 【shell 大系】Linux Shell常用技巧

    在最近的日常工作中由于经常会和Linux服务器打交道,如Oracle性能优化.我们数据采集服务器的资源利用率监控,以及Debug服务器代码并解决其效率和稳定性等问题.因此这段时间总结的有关Linux ...

  2. JavaScript实现通过的集合类

    集合是一种数据结构,用以表示非重复值的无序集合.集合的基础方法包括添加值.检测值是否在集合中,这种集合需要一种通用的实现,以保证操作效率. JavaScript的对象是属性名以及与之对应的值的基本集合 ...

  3. Hibernate 参数设置一览表

    Hibernate 参数设置一览表 属性名 用途 hibernate.dialect 一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL. 取值 fu ...

  4. Linux(CentOS 6.7)下配置Mono和Jexus并且部署ASP.NET MVC3、4、5和WebApi(跨平台)

    1.开篇说明 a. 首先我在写这篇博客之前,已经在自己本地配置了mono和jexus并且成功部署了asp.net mvc项目,我也是依赖于在网上查找的各种资料来配置环境并且部署项目的,而其在网上也已有 ...

  5. Meta标签详解(HTML JAVASCRIPT)

    Meta标签详解,在网上转的,希望对大家有用 您的个人网站即使做得再精彩,在“浩瀚如海”的网络空间中,也如一叶扁舟不易为人发现,如何推广 个人网站,人们首先想到的方法无外乎以下几种: ● 在搜索引擎中 ...

  6. 前后端分离之前端项目构建(grunt+require+angular)

    前言 前段时间做了一个项目,前端开发页面,然后把代码给到后端同学,后端同学通过vm再来渲染页面.后来才发现,这种方式简直是太low了,因为前端代码在服务端同学那里,每次前端需要更改的时候都需要去到服务 ...

  7. CyclicBarrier ------仿真赛马游戏

    import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent ...

  8. Aspose.Words基本操作

    一个非常好用的控件. 基本的操作可以参考伍大神的文章: http://www.cnblogs.com/wuhuacong/archive/2012/08/30/2662961.html 在这里补充四点 ...

  9. 转载 Android 多线程处理之多线程用法大集合

    handler.post(r)其实这样并不会新起线程,只是执行的runnable里的run()方法,却没有执行start()方法,所以runnable走的还是UI线程. 1.如果像这样,是可以操作ui ...

  10. IOS 绘制圆饼图 简单实现的代码有注释

    今天为大家带来IOS 绘图中圆饼的实现 .h文件 #import <UIKit/UIKit.h> @interface ZXCircle : UIView @end .m文件 #impor ...