当前位置: 首页 > news >正文

scp从多台机器上批量下载文件到本机(升级版)

对之前的版本进行升级,增加支持密码从命令行输入方式,增加提示那些机器上传成功或者失败提示

对于运维来说,同时管理多台机器是很辛苦的事情,特别是CDN运维需要把1000台机器上的日志下载到一台机器上,靠人工一个个下载非常费劲,为此我写了一个从多台机器批量下载到本机的小程序。

下载完后把文件放到自动按照ip生成的目录。

其中用到了expect:

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

 
  Expect使用Tcl作为语言核心。不仅如此,不管程序是交互和还是非交互的,Expect都能运用。

 
1.multi_scp_download.sh的源代码
 

    
  1. #!/bin/bash  
  2. #author: yifangyou  
  3. #create time:2011-05-17  
  4. #用来通过scp批量下载目标机器文件或者目录到指定目录  
  5. #下载完毕后分别把文件在指定目录下按照ssh_host的ip生成目录里  
  6. #例如:/root/download/1.1.1.1/a.txt /root/download/2.2.2.2/a.txt  
  7. #配置文件格式:  
  8. #ssh_hosts=("1.1.1.1" "2.2.2.2")  
  9. #ssh_ports=("22" "22") 这个可以缺省,缺省值为22,或者个数比ssh_hosts少时,使用缺省值  
  10. #ssh_users=("root" "root") 这个可以缺省,缺省值为root,,或者个数比ssh_hosts少时,使用缺省值  
  11. #ssh_passwords=("323" "222") 这个可以缺省,缺省的话需要从命令行输入,或者个数比ssh_hosts少时,使用命令行输入  
  12. #执行:sh multi_scp_download.sh conf_file_path target local_dir  
  13. if [ -z "$3" ]  
  14. then 
  15. echo "sh multi_scp_download.sh conf_file_path target local_dir";  
  16. exit;  
  17. fi  
  18. default_ssh_user="root" 
  19. default_ssh_port="22";  
  20. #upload shell script file path  
  21. scp_upload=scp_upload.sh  
  22. #configure file path  
  23. conf_file=$1  
  24. #remote host'target file or dir path  
  25. scp_target=$2  
  26. #then local file path or dir path  
  27. scp_local_dir=$3  
  28. #判断conf_file配置文件是存在  
  29. if [ ! -e "$conf_file" ]  
  30. then 
  31. echo "$conf_file is not exists";  
  32. exit;  
  33. fi  
  34. if [ ! -d "$scp_local_dir" ]  
  35. then 
  36. echo "$scp_local_dir is not exists and must be a dir";  
  37. exit;  
  38. fi  
  39. #read configure file  
  40. source $conf_file  
  41. #若是没有在配置文件里提供密码,则在命令行输入  
  42. if [ "${#ssh_passwords[@]}" = "0" ] || [ "${#ssh_passwords[@]}" -lt "${#ssh_hosts[@]}" ]  
  43. then 
  44. read -p "please input password:" -s default_ssh_password  
  45. fi  
  46. for((i=0;i<${#ssh_hosts[@]};i++))  
  47. do  
  48. #remote ssh host  
  49. ssh_host=${ssh_hosts[$i]};  
  50. if [ "$ssh_host" != "" ]  
  51. then 
  52. #remote ssh port  
  53. ssh_port=${ssh_ports[$i]};  
  54. if [ "$ssh_port" = "" ]  
  55. then 
  56. ssh_port=$default_ssh_port; #use default value  
  57. fi  
  58. #remote ssh user 
  59. ssh_user=${ssh_users[$i]};  
  60. if [ "$ssh_user" = "" ]  
  61. then 
  62. ssh_user=$default_ssh_user; #use default value  
  63. fi  
  64. #remote ssh password 
  65. ssh_password=${ssh_passwords[$i]};  
  66. if [ "$ssh_password" = "" ]  
  67. then 
  68. ssh_password=$default_ssh_password; #use default value  
  69. fi  
  70. scp_local_dir_host=$scp_local_dir/$ssh_host/  
  71. mkdir -p $scp_local_dir_host  
  72. echo "["`date +"%F %T"`"] (scp -r $ssh_user@$ssh_host:$ssh_port:$scp_target $scp_local_dir_host) start" 
  73. #scp file or dir  
  74. /usr/bin/expect scp_download.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_target" "$scp_local_dir_host" 
  75. echo "["`date +"%F %T"`"] (scp -r $ssh_user@$ssh_host:$ssh_port:$scp_target $scp_local_dir_host) end" 
  76. echo "" 
  77. else 
  78. echo "ssh_host[$i]=null" 
  79. fi  
  80. done 

2.scp_download.sh的源代码

 


 
  1. #!/usr/bin/expect  
  2. #author: yifangyou  
  3. #create time:2011-05-17  
  4. #host  
  5. set scphost "[lindex $argv 0]" 
  6. #ssh端口  
  7. set port "[lindex $argv 1]" 
  8. #ssh用户名  
  9. set scpuser "[lindex $argv 2]" 
  10. #ssh密码  
  11. set scppw "[lindex $argv 3]" 
  12. #要在远程机器上的要下载到本地的文件名或者目录  
  13. set target "[lindex $argv 4]" 
  14. #要下载的文件名或者目录  
  15. set file "[lindex $argv 5]" 
  16. spawn scp -r -P $port $scpuser@$scphost:$target $file  
  17. #设置超时时间,防止远程机器防火墙没有开,而挂起  
  18. set timeout 30  
  19. expect {  
  20. #respose: "root@1.2.3.4's password:",自动输入密码  
  21. "*password*" {  
  22. set timeout 30  
  23. send "$scppw\r" 
  24. }  
  25. #the first connect will respose "Are you sure you want to continue connecting (yes/no)? yes" 
  26. "*yes*" {  
  27. set timeout 30  
  28. send "yes\r" 
  29. set timeout 30  
  30. expect "*password*" 
  31. set timeout 30  
  32. send "$scppw\r" 
  33. }  
  34. busy {send_user "\n<error:busy>";exit 1;}  
  35. failed {send_user "\n<error:failed>";exit 2;}  
  36. timeout {send_user "\n<error:timeout>";exit 3;}  
  37. }  
  38. #Permission denied not try again,回报出错信息  
  39. expect {  
  40. "*denied*" {  
  41. send_user "\n<error:Permission denied>" 
  42. exit 4  
  43. }  
  44. "*No such file*" {  
  45. send_user "\n<error:No such file>" 
  46. exit 5  
  47. }  
  48. busy {send_user "\n<error:busy>";exit 6;}  
  49. failed {send_user "\n<error:failed>";exit 7;}  
  50. timeout {send_user "\n<error:timeout>";exit 8;}  
  51. }  
  52. exit 0 

3.配置文件格式scp.conf

 


 
  1. #ssh_hosts=("1.1.1.1" "2.2.2.2")  
  2. #ssh_ports=("22" "22") #wheen port_num < host_num use default=22,or ssh_ports is undefined use 22 as default value  
  3. #ssh_users=("root" "root") #wheen user_num < host_num use default=root,or ssh_users is undefined use root as default value  
  4. #ssh_passwords=("323" "222") #wheen password_num < host_num use default=input password,or ssh_users is undefined use input password 

4.运行代码
找一台机器可以和要上传的机器联通,安装好expact
把scp_download.sh,multi_download.sh,scp.conf放到同一个目录下,运行multi_scp_download.sh即可
5.运行效果

相关文章:

  • WordPress的url链接带“/”反斜杠
  • 解决C3P0在Linux下Failed to get local InetAddress for VMID问题
  • Surface 2.0 SDK在WPF中应用
  • 基于GNS3的独臂路由配置
  • DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表
  • Python基础之面向对象
  • C#加密汇总
  • 压缩打包介绍,gzip、bzip2、xz压缩工具
  • eclipse不能自动编译工程的解决方法
  • 普天发布新一代配线架,终结争论?
  • Server2008 安装 Zune
  • Asp.Net 开放式并发处理(和保守性并发)介绍
  • 如何在Windows XP上安装Windows Phone Developer Tools
  • 使用PowerShell配置IP地址
  • 基于jquery的常见函数封装
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 〔开发系列〕一次关于小程序开发的深度总结
  • bootstrap创建登录注册页面
  • DataBase in Android
  • Docker: 容器互访的三种方式
  • Java编程基础24——递归练习
  • React的组件模式
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vim Clutch | 面向脚踏板编程……
  • web标准化(下)
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 构建二叉树进行数值数组的去重及优化
  • 京东美团研发面经
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端性能优化--懒加载和预加载
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 一个完整Java Web项目背后的密码
  • 译有关态射的一切
  • 你对linux中grep命令知道多少?
  • Python 之网络式编程
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • (¥1011)-(一千零一拾一元整)输出
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (C#)一个最简单的链表类
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (java)关于Thread的挂起和恢复
  • (k8s中)docker netty OOM问题记录
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (初研) Sentence-embedding fine-tune notebook
  • (二)斐波那契Fabonacci函数
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (十) 初识 Docker file
  • (一)插入排序