一个开源项目中用到的bash shell脚本

请看系统鸟瞰图:

因为笔者所在的地方并无可用的宽带和Wifi,所以暂且只能采用上图中的联网方法,使用ssh走手机GPRS流量的方法进行远程操作云风典藏官网的服务器,以完成所有任务。
  关于云风典藏的更多信息,请看文章《四个月的隐居和一个新的开源项目——云风典藏》。

第一步:SSH安全设置
  服务器现在由我们全部负责,远程登录的安全为重中之重。
  1.创建一普通用户,以后只使用此用户来远程登录系统;
  2.修改root密码;
  3.修改sshd的配置:

1 #vim sshd_config file
2 Port 1111
3 Port 33333
4 Port 47873
5 AllowUsers username
6 MaxAuthTries 2

修改sshd的默认端口22,增加多个自定义端口,免得被人打扰而使得自己登不上服务器,只允许username用户通过sshd登录系统。
  修改完毕,保存,重启sshd。
 
第二步:开始面向目标服务器的抓取工作
  写好脚本,验证无误。

$nohup bash grab.sh &>grab.sh.log &

使用nohup来免疫当父进程退出时发来的hangup信号,使得任务真正的能够后台运行,即使当前的ssh连接因为GPRS网络不稳定(经常会遇到)而意外中断,仍然不会影响到我们的grab任务。
  另外提醒一点,刚开始我使用并发数十个进程同时抓取目标(因为任务量很大,为了节约时间),最后才发现很多子任务都失败了,这肯定是因为对方的Web服务器设置了单个IP并行连接的限制而导致的,于是我更改为单进程抓取,出错率显著的降低了。
  这时候就可以去睡觉了,明天早上再看看grab日志有无异常。
  第二天早上,当任务完成后:

$ ls -Slr *html | more

查看单个任务出错的情况。

$ find ./*html -size -5557c >error.list

找到阈值,使用find将所有出错的任务文件名称打印到一个文件里。

第二次再专门针对出错的任务进行抓取,正常情况下出错的概率很低,所以这里的任务量就会很小。

如果有多个目标服务器的抓取任务的话,可以采用多个任务同时进行抓取的方法,因为很多时候,是对方服务器跟不上我们的请求,而非我们的网络带宽不够大。

第二步:对抓取到的html与小图片进行处理  

find、sed、awk、grep这四把利器对于一般的文本处理要求毫无压力。

$grep -o ‘[一-龥]‘ 

过滤出utf-8中的20902个汉字

$grep -oP ‘re‘

grep的-P即--perl-regexp,正则表达式的断言绝对好用 :)

#!/bin/bash
ls *html | while read i
do
    buf=`cat $i`
    echo $buf | while read j
    do
        #process......
    done
done

将很多字符缓存到bash的变量中,有时候很方便 :)

$ iconv -c -f utf-8 -t gbk

windows默认gbk,而linux默认utf-8,所以上述命令很常用。
  其选项-c从输出中忽略无效的字符,如果不使用此选项当iconv遇到输入的非法字符时将会出错退出,导致文件流转码被中途腰斩。

$ 7za x -r dir.7z
$ 7za a -r ety.7z ety/

当需要在linux与windows上来回传送文件时,中文的文件名很可能会乱码,原因已在上面阐述了。而7za默认能保存和转换文件名的编码,使得文件名乱码事件不会发生。另外,7z号称最强压缩算法,而且是免费的。

第三步:文件名称加密转码 请看下图:

有时候我们并不想将我们的文件访问路径直接给用户,而是想转成一组无规律可循的编码表示,以防止用户进行迭代抓取(:也许还有其他原因:)
  这时候我们希望将完整的文件名路径如:

/img/hanzi/xiaozhuan/9053.gif

  单一可逆的映射到如

/img/TI87980FHGJHK899B.gif

的路径上,这时候就需要一些转换了 :)

上述为关键详细过程,下面提供一个随机加密模组生成bash shell script:

#####隨機打散數組 随机打散数组
ara=‘0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ‘
while true
do
    if [ -z "$ara" ]
    then
        break
    fi
    b=$((RANDOM%62))
    #echo $b
    b="${ara:${b}:1}"
    #echo "<$b>"
    if [ -z "$b" ]
    then
        continue
    fi
    ara=${ara/${b}/}
    echo $b
done | tr -d ‘\n‘
echo ""
# output:$C8O1Fb0oPlkmzycSpZMuEtXBwgLnQUeHvArRDf67as9I5xJdWNjhi3TVGqK42Y

上述算法思想很有趣,感兴趣的可以仔细看一下:)
  全部实现代码如下:

 1 function yunencode() {
 2
 3   base64 | tr ‘0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ‘ ‘C8O1Fb0oPlkmzycSpZMuEtXBwgLnQUeHvArRDf67as9I5xJdWNjhi3TVGqK42Y‘ |
 4   sed ‘s|A|AA|g‘ | sed ‘s|+|AB|g‘ | sed ‘s|/|AC|g‘ | sed ‘s|=|AD|g‘ |  5   sed ‘s|.*$|&AE|g‘ | tr -d ‘\n‘
 6 }
 7
 8
 9 function yundecode() {
10
11     ###########
12     declare ycpre=""
13     declare ycnow=""
14     declare ycn=0
15     sed ‘s|.|&\n|g‘ | while read ycnow
16     do
17         #echo -n 1 $ycnow 1
18         #echo yun:$ycpre:ycnow
19         ycn=$((ycn+1))
20             #echo -n "$ycpre$ycnow"
21             if [ "$ycpre" = "A" ]
22             then
23               if [ "$ycnow" = "A" ]
24               then
25                   echo -n ‘A‘
26                   ycpre=‘‘
27               elif [ "$ycnow" = "B" ]
28               then
29                   echo -n ‘+‘
30                   ycpre=‘‘
31               elif [ "$ycnow" = "C" ]
32               then
33                   echo -n ‘/‘
34                   ycpre=‘‘
35               elif [ "$ycnow" = "D" ]
36               then
37                   echo -n ‘=‘
38                   ycpre=‘‘
39               elif [ "$ycnow" = "E" ]
40               then
41                 echo ""
42                 ycpre=‘‘
43               else
44                   echo -n ‘A‘
45                 echo -n $ycnow
46                 ycpre=‘‘
47                 fi
48             else
49                 if [ "$ycnow" = ‘A‘ ]
50                 then
51                     ycpre=‘A‘
52                 else
53                     ycpre=‘‘
54                     echo -n $ycnow
55                 fi
56             fi
57         #echo ""
58     done | tr ‘C8O1Fb0oPlkmzycSpZMuEtXBwgLnQUeHvArRDf67as9I5xJdWNjhi3TVGqK42Y‘  ‘0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ‘ 59     | base64 -d
60 }
61
62
63 function yunencode0win() {
64     yunencode | sed ‘s|0|00|g‘ | sed ‘s|[a-z]|0&|g‘ | tr ‘a-z‘ ‘A-Z‘
65 }
66
67 function yundecode0win() {
68     declare ycpre=""
69     declare ycnow=""
70     sed ‘s|.|&\n|g‘ | while read ycnow
71     do
72         if [ "$ycpre" = "0" ]
73         then
74             if [ "$ycnow" = "0" ]
75             then
76                 echo -n "0"
77                 ycpre=""
78             elif echo "$ycnow" | grep -Po ‘[A-Z]‘ &>/dev/null
79             then
80                 ycnow=` echo "$ycnow" | tr ‘A-Z‘ ‘a-z‘ `
81                 echo -n "$ycnow"
82                 ycpre=""
83             else
84                 echo -n "0"
85                 echo -n "$ycnow"
86                 ycpre=‘‘
87             fi
88         else
89             if [ "$ycnow" = "0" ]
90             then
91                 ycpre=‘0‘
92             else
93                 ycpre=‘‘
94                 echo -n "$ycnow"
95             fi
96         fi
97     done | yundecode
98 }

上述代码两次写成,所以很多都可以在进行速度优化的,比如yundecode0win对应的两个状态机可以简化为一个,不过逻辑稍微复杂些而已。
  yunencode0win与yundecode0win并没有实现DES3二进制加密的部分,因为使用管道配合openssl即可轻松实现:

$ dd if=a.bin | openssl des3 | yunencode0win
$ echo ‘yunencoded-msg‘ | yundecode0win | openssl des3 -d | dd of=a.bin.new

这里有两把钥匙,一把是你的openssl password,一把是你的随机tr模板,如果你觉得一次DES3加密太过简单,你可以使用多轮多种加密算法辗转处理......

第四步:从远方的服务器上传文件到网络云盘

使用bypy.py在服务器上upload文件到百度云盘,这是最后一步了。
  如果你想要加密你的文件:

$ dd if=v1.01.7z | openssl des3 | dd of=v1.01.7z.abc

另外7z也支持加密压缩。

感谢你花时间来阅读这篇文章! 

附录:

  《从VPS上传文件到百度网盘》、《四个月的隐居和一个新的开源项目——云风典藏

时间: 2024-12-28 01:32:02

一个开源项目中用到的bash shell脚本的相关文章

www808888webcom基金的一个开源项目19908836661也是apache基金的一个开源

Flume也是apache基金的一个开源项目,由cloudera公司开发的一款分布式.高可靠.高可用的日志传输工具.其以agent为一个单位,agent由source.channel和sink构成.一个agent最少由一个source.channel和sink构成,数量可以自由组合 Source主要用来收集源数据,并对源数据进行反序列化.Source在读取数据文件时,会遍历日志文件中的每一行,并把这一行封装在一个event当中,一个event包含一个header和一个body,header是一个

如何参与一个开源项目!

1.首先在github上注册一个自己的账号 2.然后在左上部分搜索一个开源项目,比如说我的项目syj-ratelimit 3.进入项目之后,单击右上角的fork按钮,github就会在你的帐户下fork一个同样的项目. 4.此时点击右上角自己的头像,可以看到一个your repositories,点击进入就可以看到刚才的那个项目了 5.现在你就可以在这个项目里取发挥你的个人才智进行修改bug.开发新功能等各种方式的贡献了 6.当你贡献完毕后就可以把你的贡献推荐给这个项目的开发者了.再次打开git

8.15_Linux之bash shell脚本编程入门篇(二)以及文件查找和压缩的使用

bash shell脚本编程入门篇(二) read命令的使用 作用: 使用read来把输入值分配给一个或多个shell变量: -p指定要显示的提示 -t TIMEOUT read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量 EX.read -p "Enter a filename:" FILE 条件选择之if的使用 if的作用:选择执行(注意:if语句可嵌套) 单分支 if 判断条件;then 条件为真的分支代码 fi EX.单分支案例 双分支 if

8.11_Linux之bash shell脚本编程入门篇(一)

什么是bash shell脚本编程? 答:Linux里面有多种shell,而CentOS和redhat的默认shell是bash shell.至于shell脚本,这个跟windows操作系统里面的批处理文件有点像(.bat的文件).不知道大家还是否记得Linux的哲学思想吗?其中有那么两点点:由众多目的的单一应用程序组成:一个程序只做一件事,且做好:组合目的的单一的小程序完成复杂的任务.我觉得shell脚本编程就很好的体现了这个哲学思想.shell脚本利用shell的功能缩写的一个"程序&quo

系统管理中 bash shell 脚本常用方法总结

FROM: http://www.cnblogs.com/hunterfu/archive/2010/02/23/1672129.html 在日常系统管理工作中,需要编写脚本来完成特定的功能,编写shell脚本是一个基本功了!在编写的过程中,掌握一些常用的技巧和语法就可以完成大部分功能了,也就是2/8原则. 1. 单引号和双引号的区别 单引号与双引号的最大不同在于双引号仍然可以引用变量的内容,但单引号内仅是普通字符 ,不会作变量的引用,直接输出字符窜.请看如下例子: [[email protec

BASH SHELL 脚本基础

什么是shell     Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口.它是命令语言.命令解释程序及程序设计语言的统称. shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层.当从shell或其他程序向Linux传递命令时,内核会做出相应的反应.            shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用.用户在提示符下输入的命令都

Bash Shell脚本编程笔记总结(一)

本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变量找到外部命令:把命令提交给内核启动为进程: 编程环境: 流程控制语句: 顺序执行: 循环执行: 选择执行: 条件测试:真.假 $? 命令的状态结果: 0: 真 1-255: 假 过程式的编程语言的元素:变量.流程.函数.数组 变量:局部变量.本地变量.环境变量.位置参数变量.特殊变量 变量: 数值

Bash Shell脚本编程笔记总结(二)

本文接上一部分:Bash Shell脚本编程笔记总结(一) 数组: 连续的多个独立内存空间,每个内存空间相当于一个变量 数组元素:数组名+索引 索引:从0开始编号 声明数组: declare -a ARRAR_NAME 关联数组: declare -A ARRAY_NAME 支持稀疏格式: 数组元素的赋值: (1) 一次只赋值一个元素 ARRAY[index]=VALUE a[0]="hello" (2) 一次赋值全部元素 ARRAY=("mon" "tu

Linux Shell——bash shell 脚本简介

bash shell 脚本简介 shell 运行环境 如果你运行的是 Unix 或 Linux 系统,例如 Ubuntu,Red Hat,SUSE Linux,还有macOS,都是内置了 bash shell 的,所以你不需要额外配置所谓的开发环境. 我的 shell 环境是 macOS Sierra 版本,如果你用的是其他 Linux 系统,后面的例子基本上都是可以运行的. 首先,打开Terminal 命令行,先检查下你的系统的 shell 版本: echo $BASH_VERSION bas