shell脚本实现文件的自动上传以及下载 scp sftp lftp 还有expect命令
转至:
最近需求要求定期从一个[定期更新的文件] 中解析员工信息 ,插入到数据库中.
按理来说很简单, 无非就是io流读文件,然后crud balalalala.....
其实不是的, 我我写的这个接口 ,要实现从远程服务器上获取文件然后入库操作 . . . 问题来了, 我怎么去读文件.
这样就用到了linux的命令了 ,大致来说 , 从远程服务器上获取文件有好几种方式 , scp快速获取 sftp建立ssh连接 ,lftp连接 好像还有个rsync什么的,这个没记住 ....
大致命令为
下载: 如果(-p端口号不好使 就替换成 -oPort=端口号)
scp -p端口号 远程服务器用户@远程服务器ip:文件路径 本地存放路径
例子: scp -p22 root@10.10.10.168:/usr/wang.txt /usr/wang.txt 这个好像不能scp的时候改名字
sftp -p端口号 远程服务器用户@远程服务器ip 建立连接之后:
get 要下载的文件路径+文件名 本地存储路径
put 本地存储路径 要上传的文件路径+文件名
quit 或者exit 可以退出ssh连接
例子 懒得写了, 直接截屏吧
lftp 这个我是和sftp 同时用的 有一个好处可以免登陆的:
现在上图:.......
码的公司服务器好像断了 (掀桌!), 算了不截屏了 , 老老实实码字吧.. . . . . . .
这个是点击之后 , 就会进入
这个时候 cd 远程服务器目录 这个命令就是进入远程服务器的目录
lcd 本地存放目录 这个额命令就是进入本地需要存放的目录
get 需要下载文件名
put 需要上传的文件名
quit或者 exit 退出
其实我要说的命令直接百度就能搜到 , 接下来就是实现自动上传或下载了 ,大致有三种 , 我实现了有两种 , 看这个大神的
第一种:使用lftp+sftp 命令
第二种:使用expect 命令
第三种:配置免密 看这个写得很清楚点击打开链接 大致就是使用- keygen 生成密钥,将公钥交给远程服务器以配置免登录
注意:你用那个用户获取的密钥,你就要cd到那个用户的cd /用户名/.ssh/公钥文件 下, 我就是用admin用户获取到 ,但是发现进不去/root/.ssh/ 目录下 , 大概我是个接触脚本两天的小白把 ,maybe。。。。
第一种:
<strong>#!/usr/bin/bash // 这个头部很重要</strong>
trandt=`date +%Y%m%d`
lastdt=`date -d "$trandt -2 day " +%Y%m%d`
var1=dim_user_
var2=.txt
#文件名
filename=${var1}${lastdt}${var2} //需求上说的是文件名跟日期变动的,所以我的文件名这么写 ,可以写死的!
USER=wodemingzi
#密码
PASSWORD=wodemima
#下载文件目录
#LOCAL=/usr/local/src/ //文件admin没有读写权限
LOCAL=/home/admin/ //尽量放在这个目录下吧 有的应用没有其他文件夹的读写权限
#FTP目录(待下载文件目录)
REMOTE=/jd_tfm_file/
#银联IP
IP=10.10.10.168
#端口
PORT=2374
lftp -u ${USER},${PASSWORD} sftp://${IP}:${PORT}<<EOF
cd ${REMOTE}
lcd ${LOCAL}
#需要下载的文件
get ${filename}
EOF
这个脚本其实不算难 , 但是实现的时候非常的艰难 , 首先是脚本不能执行的问题 , 需要注意的地方我加粗了 这个文件的名字为lftp.sh
是个shell脚本文件, 需要 是sh lftp.sh 来运行的 .
其次就是文件不能执行的问题:
文件权限需要用 chmod 777 脚本文件.sh 获取权限
+++++++++++++++++++++++++++今天先写到这, 明天再写吧++++++++++++++++++++++++++++++++
继续写:
文件获取权限之后 ,使用sh lftp.sh就可以执行了
但是有一个问题, 看贴图吧
我使用cat命令,把脚本粘贴到命令行执行,
wht?!!!没有报告任何错误 , 直接就把远程服务器文件get到了我本地指定目录里面。
错误.jpg
假装这里有图,
发现执行到, 这里 , 就不执行了 , 始终搞不懂到底是为啥 , 百度了各大资料, 有人说 这是lftp命令没装好, 有人说这是没有指定目录, 还有人用./wang.sh 的方式 ,还有人说是用户权限的问题 , 我把代码粘出来就能执行你告诉我是权限的问题??!!!
总之全他么的不好使 ,最后本人媳妇(大神)告诉我 ,你这个文件的声明不对吧,,,shell脚本声明头应该是这样的
#!/usr/bin/bash
看到我之前发的截图吗 , 头部明显不太对 , 好吧, 然后我就改了 ,然后继续用
sh wang.sh
发现还是不好使 ; 报的错不粘出来了 , 这次是真的没办法了, 我就放弃了一段时间 ,然后干别的去了......
=======n小时后, 我又开始验证这段脚本 了, 不好使 , 不知道怎么回事,我进入了这个大神的博客 , 我其实不想验证的,因为我一开始就害怕脚本是dos格式的 ,我就全删了,然后在linux中手打了一遍的......
反正闲的蛋疼, 我就用
vi wang.sh
按Esc , 输入 冒号 ff见下面
: set ff ===>>> 得到的他么的竟然是 'dos' , !!!!!!!!!!!这回真的是伤了
先弄好了吧 , 输入 冒号 set ff=unix
: set ff=unix ,==>>>>再输入 :set ff 发现就变成 unix 了 .
好这次我继续敲:
sh wang.sh ; ^_^,终于成功了!!!!
第一种方式完成!!!!!
总结: 脚本
第一要先验证脚本格式是什么类型的,是dos 还是unix 的 ,这个很重要 链接在这里
https://blog.csdn.net/chengxuyuanyonghu/article/details/47340123
第二,一定要注意头部一定要正确, 确保你的命令在linux中已经安装了
第三,确保你的脚本文件时一个可执行的文件 , 不可执行,使用 chmod 777 文件名 获取权限
第四:这个我最后遇到了, 不过懒得再复述了. , 在你的脚本中设置 本地存放路径(lcd 路径) 的时候 ,一定要确保你的当前用户(不管是root还是 admin还是其他) 是拥有这个目录的读写权限的,这个存放目录建议就放在/home/用户名/ 这个目录下最靠谱.
第五: 没了.(对了,就算做到了这些, 也要确保远程服务器和本地服务器的连通性 ,先使用单行命令,是不是能连通 ,然后再去测脚本)
============================o(╥﹏╥)o=============================
第二种方式: 使用expect 命令的方式 ,
很不幸, 我的这个不好使 , 一直报告找不到
spawn not found
我确实安装了 expect 命令
贴一下代码吧
直接用scp -p22 root@10.10.10.153:/export/123.txt /home/root/123.txt 可以拉取到我本地
用 sftp -oPort(同一公司内服务器用-p就行)=22 root@10.10.10.153 , 可以直接连接上 不需要输入密码了;
然后 cd /export/ ===>>>到远程目录下
cd /home/root/ ===>>>到本地目录下
get 文件名 ===>>>妥妥的复制过来了(put也一样)
lftp 上面写过了.
把java代码也粘一下.(目前还不想使用github,因为比较菜 ,不想过多把精力放在这上面 ,文章也懒得排版,想到哪就写到哪了.....有问题加我球球号952288306 交流)
执行脚本的java代码:
import java.io.*; /**
*
* @author
* 执行脚本的工具类
*/
public class JavaLinuxManager { public String Linuxscp(String img,String encode){
String msg = null;
try {
Process ps = Runtime.getRuntime().exec(img);
ps.waitFor();
msg = loadStream(ps.getErrorStream(),encode);
System.err.print(msg);
ps.destroy();
} catch (Exception e) {
e.printStackTrace();
}
return msg;
} static String loadStream(InputStream in,String encode) throws IOException {
//把所有的数据读取到这个字节当中
byte[] b = new byte[1024];
//声明一个int存储每次读取到的数据
int i = 0;
//定义一个记录索引的变量
int index = 0;
//循环读取每个数据
while((i=in.read())!=-1) {//把读取的数据放到i中
b[index] = (byte) i;
index++;
}
return new String(b,encode==null?"utf-8":"gbk");
} // public static void main(String[] args) throws Exception {
// File file = new File("d:a.txt");
// FileInputStream fileIn = new FileInputStream(file);
// String s = loadStream(fileIn, FileUtils.encoded(file));
// System.out.println(s);
// }
}
controller很简单, 就是 不少注解是swagger的 可以忽略 ,主要看加粗的部分
@ApiOperation(value = "執行java脚本")
@RequestMapping(value = "/runtime/img", produces = "application/json;charset=utf-8")
public RespData<Map<String, Object>> img(
@ApiParam(value = "平台ID", required = true) @RequestParam("platformId") Long platformId,
@ApiParam(value = "脚本或者文件路径(chmod 777 ./WEB-INF/shs/sftp.sh)", required = true) @RequestParam("img") String img, HttpServletRequest request,
@ApiParam(value = "验证码", required=true) @RequestParam(value = "authcode",required = true)String authcode) {
try {
// chmod 777 ./WEB-INF/shs/sftp.sh
if ("XXX一个验证码省得别人恶意拼接XXXXX".equals(authcode)){
JavaLinuxManager unix = new JavaLinuxManager();
String linuxscp = unix.Linuxscp(img, null);
Map<String,Object> map = new HashMap<>();
map.put("msg",linuxscp);
return RespData.success(map);
}else {
return RespData.error("0000","验证码失败!!!");
}
} catch (Exception e) {
LOG.error("执行异常!", e);
e.printStackTrace();
}
return RespData.error("0000", "执行异常");
}
附一个文件工具类:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List; import org.slf4j.Logger; /**
* 读取文本工具类
* @author
*
*/
public class FileUtils { private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(FileUtils.class); /**
* 判断文件是否存在 不存在创建空文件
* @param file
* @return
* @throws IOException
*/
public static boolean isExistFile(File file) throws IOException {
// 判断是否存在
if (file.exists()) {
// 判读是否是一个文件
return file.isFile();
} else if (file.length() == 0) {
LOG.info("文件内容为空");
} else {
LOG.info("文件不存在!");
}
return false;
} /**
* 判断文件的编码方式
* @param file
* @return
* @throws IOException
*/
public static String encoded(File file) throws IOException{
InputStream in = new FileInputStream(file);
byte[] b = new byte[3];
in.read(b);
in.close();
if (b[0]==-17&&b[1]==-69&&b[2]==-65) {
// 一般来说,utf-8 的前三个字符为上述三个
LOG.info("文件utf-8编码!");
return "utf-8";
}else{
LOG.info("文件gbk编码!");
return "gbk";
}
}
/**
* 读取txt文件 返回Sting
* @param path
* @return
* @throws IOException
*/
public static String readTXTFile(String path) throws IOException {
File file = new File(path);
boolean existFile = isExistFile(file);
if (existFile) {
LOG.info("文件存在且内容非空!");
String charset = encoded(file);
InputStreamReader reader = new InputStreamReader(new FileInputStream(file), charset);
BufferedReader bf = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
String text = "";
while ((text = bf.readLine()) != null) { sb.append(text);
sb.append(";");
//sb.append("\r\n");
}
String sbNew = sb.substring(0, sb.length() - 1);
reader.close();
bf.close();
return sbNew;
}
return "";
} }
shell脚本实现文件的自动上传以及下载 scp sftp lftp 还有expect命令的更多相关文章
- Linux学习笔记:使用shell脚本实现ftp的自动上传下载
在 Linux 下可以利用 Shell 实现 ftp 文件的自动上传和下载,封装至 crontab 更可实现定时调度. 1.ftp自动登录批量下载文件 ##### 从ftp服务器上的/home/dat ...
- shell脚本中文件测试
shell脚本中文件测试 author:headsen chen 2017-10-17 14:35:19 个人原创,转载请注明作者,否则 依法追究法律责任 [ -f filename ] ...
- Shell脚本统计文件行数
Shell脚本统计文件行数 转自 http://www.jb51.net/article/61943.htm 示例:row_count.sh文件 awk '{print NR}' row_cou ...
- (转)shell脚本之文件测试操作符及整数比较符
shell脚本之文件测试操作符及整数比较符 原文:http://www.cnblogs.com/Steward-Xu/p/6722592.html 一.文件测试操作符: 在书写测试表达式是,可以使用一 ...
- shell 脚本大文件处理
shell 脚本大文件处理 字符串处理 s='{"_id":{"$oid":"59b73d80930c17474f9f050d"},&qu ...
- Linux使用Shell脚本实现ftp的自动上传下载
1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地的/home/databackup#####!/bin/bashftp -n<<!open 1 ...
- 利用shell脚本统计文件中出现次数最多的IP
比如有如下文件test.txt 1 134.102.173.43 2 134.102.173.43 3 134.102.171.42 4 134.102.170.9 要统计出现次数最多的IP可 ...
- Shell脚本实现文件遍历和删除操作
本文需要实现的功能如下:某文件夹下具有由按数字编号命名的文件夹,需要删除除最大编码外的文件. 具体实现 大致思路:循环遍历该文件夹下所有文件,正则匹配出最大编码文件:然后循环文件,删除除最大编码外的文 ...
- shell脚本学习-文件包含
跟着RUNOOB网站的教程学习的笔记 和其他语言一样,shell也可以包含外部脚本.这样可以很方便的封装一些公用的代码作为一个独立的文件.shell文件包含的语法有两种形式 . filename # ...
随机推荐
- Device or resource busy
格式化磁盘显示忙碌,如何解决呢? [root@jp33e503-11-8 ~]# mkfs.xfs /dev/sdc mkfs.xfs: cannot open /dev/sdc: Device or ...
- Redis 源码简洁剖析 03 - Dict Hash 基础
Redis Hash 源码 Redis Hash 数据结构 Redis rehash 原理 为什么要 rehash? Redis dict 数据结构 Redis rehash 过程 什么时候触发 re ...
- java 多线程 start方法 run方法 简单介绍。
一 start开启一个多线程, run 只是一个内部的方法. package com.aaa.threaddemo; /* * start方法的作用? * 在 Java中启动多线程调用的是start方 ...
- k8s-基础篇
搭建k8s环境 Myapp镜像部署扩容pod自愈负载均衡DNS外网访问滚动更新YAML方式部署独立部署podRS副本控制器Deployment-自动扩容Deployment-更新版本Deploymen ...
- CTF入门学习5-> 前端JavaScript基础
Web安全基础 JavaScript的实现包括以下3个部分: 1)核心语法:描述了JS的语法和基本对象. 2)文档对象模型 (DOM):处理网页内容的方法和接口 3)浏览器对象模型(BOM):与浏览器 ...
- 标签显示模式(display)
非洲黑人: 皮肤内黑色素含量高,以吸收阳光中的紫外线,保护皮肤内部结构免遭损害,头发象羊毛一样卷曲,使每根卷发周围都有许多空隙,空隙充满空气,卷发有隔热作用. 欧洲白人: 生活寒带或着是说常年温度较低 ...
- Centos 7 下部署Django + uWSGI + Nginx
1.废话 之前利用Django写了些测试工具,一直是直接 python manage.py runserver 8081这么来用的.用户量不大,倒也不影响什么.uWSGI+Nginx的性能肯定要好,s ...
- Java线程状态介绍
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11867086.html Java 线程状态介绍: Java官方文档中对Java线程的几种状态做 ...
- ios 类别和扩展-赵小波
类别 @interface ClassName ( CategoryName ) // method declarations @end Category在iOS开发中使用非常频繁.尤其是在为系统类进 ...
- 反射(reflection),通过反射创建对象
简单尝试: import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public cl ...