转至:

最近需求要求定期从一个[定期更新的文件] 中解析员工信息 ,插入到数据库中.

按理来说很简单,  无非就是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命令的更多相关文章

  1. Linux学习笔记:使用shell脚本实现ftp的自动上传下载

    在 Linux 下可以利用 Shell 实现 ftp 文件的自动上传和下载,封装至 crontab 更可实现定时调度. 1.ftp自动登录批量下载文件 ##### 从ftp服务器上的/home/dat ...

  2. shell脚本中文件测试

    shell脚本中文件测试 author:headsen chen  2017-10-17  14:35:19 个人原创,转载请注明作者,否则 依法追究法律责任 [ -f  filename  ]   ...

  3. Shell脚本统计文件行数

    Shell脚本统计文件行数 转自 http://www.jb51.net/article/61943.htm    示例:row_count.sh文件 awk '{print NR}' row_cou ...

  4. (转)shell脚本之文件测试操作符及整数比较符

    shell脚本之文件测试操作符及整数比较符 原文:http://www.cnblogs.com/Steward-Xu/p/6722592.html 一.文件测试操作符: 在书写测试表达式是,可以使用一 ...

  5. shell 脚本大文件处理

    shell  脚本大文件处理 字符串处理 s='{"_id":{"$oid":"59b73d80930c17474f9f050d"},&qu ...

  6. Linux使用Shell脚本实现ftp的自动上传下载

    1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地的/home/databackup#####!/bin/bashftp -n<<!open 1 ...

  7. 利用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可 ...

  8. Shell脚本实现文件遍历和删除操作

    本文需要实现的功能如下:某文件夹下具有由按数字编号命名的文件夹,需要删除除最大编码外的文件. 具体实现 大致思路:循环遍历该文件夹下所有文件,正则匹配出最大编码文件:然后循环文件,删除除最大编码外的文 ...

  9. shell脚本学习-文件包含

    跟着RUNOOB网站的教程学习的笔记 和其他语言一样,shell也可以包含外部脚本.这样可以很方便的封装一些公用的代码作为一个独立的文件.shell文件包含的语法有两种形式 . filename  # ...

随机推荐

  1. golang中channel

    1. Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication). 2. select package main im ...

  2. DQL语句总结

    6.DQL语句总结 select ... from ... where ... group by ... having ... order by ... limit .... 执行顺序? 1,from ...

  3. Device or resource busy

    格式化磁盘显示忙碌,如何解决呢? [root@jp33e503-11-8 ~]# mkfs.xfs /dev/sdc mkfs.xfs: cannot open /dev/sdc: Device or ...

  4. mysql加强(4)~多表查询

    mysql加强(4)~多表查询:笛卡尔积.消除笛卡尔积操作(等值.非等值连接),内连接(隐式连接.显示连接).外连接.自连接 一.笛卡尔积 1.什么是笛卡尔积: 数学上,有两个集合A={a,b},B= ...

  5. Jupyter Notebook 更改字体、字体大小、行高

    (废话):今天在做实验的时候遇到了一点问题,就问了问本科的室友,结果室友推荐我使用Jupyter Notebook来写代码,以前看其他同学使用过,但是一直在用Pycharm写,需要的时候顶多是Debu ...

  6. eureka的简单介绍,eureka单节点版的实现?eureka的自我保护?eureka的AP性,和CP性?

    注意!!! 这是对上一篇博客 springcloud的延续,整个项目的搭建,来源与上一篇博客.一.什么是eureka? // eureka是一个注册中心,实现了dubbo中zookeeper的效果! ...

  7. AQS源码一窥-JUC系列

    AQS源码一窥 考虑到AQS的代码量较大,涉及信息量也较多,计划是先使用较常用的ReentrantLock使用代码对AQS源码进行一个分析,一窥内部实现,然后再全面分析完AQS,最后把以它为基础的同步 ...

  8. Linux curl命令进行网络请求

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11841353.html 1. curl get请求: curl http://www.baid ...

  9. iOS 性能优化系列

    Objective-C 高性能的循环 使用 Swift 和 Objective-C 执行 iOS 内存管理的 7 个简单技巧 @autoreleasepool-内存的分配与释放

  10. SQL 在数据库中查找拥有此列名的所有表

    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME='Column' #"Column"为要查询 ...