存档

文章标签 ‘linux’

Shell字符串分割与随机访问

2017年11月10日 没有评论

    Shell经常做的一项工作就是文本处理,通过组合grep、awk、sed等来实现查找、分割、替换、删除等操作。今天说一下对单行字符串的分割处理方法。先看代码:

_uas="Mozilla/5.0 (Linux; Android 5.1.1; Redmi Note 3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Mozilla/5.0 (Linux; Android 4.4.4; 2014813) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Linux; Android 6.0.1; SM-G9008W) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Mozilla/5.0 (Linux; Android 5.0.2; Redmi Note 2) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19"

#生成随机索引
_rand_index=$(expr $RANDOM % 4) 

#设置新的分隔符
OLD_IFS="$IFS"
IFS="|" 
#将UA字符串分割到_arr数组中
_arr=($_uas) 
IFS="$OLD_IFS"

#通过下标访问数组中的元素。
_ua=${_arr[$_rand_index]}

    _uas包含以竖线|分隔的4个安卓UA,我想要随机取其中的一个UA来用。这涉及到两点需求:生成一个随机索引,将字符串按照指定的分隔符来分隔。

    Shell生成随机数的方法可以如上面代码一样直接取系统环境变量$RANDOM也可以通过date +%s的方法获取当前的秒数,再和数组长度取模来实现。当然通过系统时间的方法获得的随机数有可能并不很随机,特别是在操作间隔很短的情况下。

    单行字符串分割可以通过awk来实现,然后分别打印各列的值。但是通过设置系统IFS的方法看起来更直接,能够直接通过($string_line)将元素保存在新的数组中,这样就可以以下标的方式来访问。

    Shell还是博大精深的,不常用不足以体会其便捷与强大。

分类: Shell, 开发 标签: ,

Httpry:简明http抓包工具

2017年7月27日 没有评论

tcpdump是流量分析时最常用的抓包工具,功能很强大。抓取http get交互消息的常用命令是:

tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 -w eth0-http.pcap

通常我们会把抓取的http包保存成文件,然后用wireshark打开分析。

有时候,我们不需要对流量观察得特别深入,仅仅是看一下有什么样的流量,不需要存盘分析。

使用tcpdump的话输出内容不直观,比如wget http://www.baidu.com/的输出如下:

15:05:27.837705 00:16:3e:04:af:53 > ee:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 165: (tos 0x0, ttl 64, id 18764, offset 0, flags [DF], proto TCP (6), length 151)
139.129.205.48.53353 > 220.181.112.244.80: Flags [P.], cksum 0xa6e5 (incorrect -> 0xe0b0), seq 2930938556:2930938667, ack 65362085, win 115, length 111
0x0000: 4500 0097 494c 4000 4006 4ab9 8b81 cd30 E…IL@.@.J….0
0x0010: dcb5 70f4 d069 0050 aeb2 92bc 03e5 58a5 ..p..i.P……X.
0x0020: 5018 0073 a6e5 0000 4745 5420 2f20 4854 P..s….GET./.HT
0x0030: 5450 2f31 2e30 0d0a 5573 6572 2d41 6765 TP/1.0..User-Age
0x0040: 6e74 3a20 5767 6574 2f31 2e31 3220 286c nt:.Wget/1.12.(l
0x0050: 696e 7578 2d67 6e75 290d 0a41 6363 6570 inux-gnu)..Accep
0x0060: 743a 202a 2f2a 0d0a 486f 7374 3a20 7777 t:.*/*..Host:.ww
0x0070: 772e 6261 6964 752e 636f 6d0d 0a43 6f6e w.baidu.com..Con
0x0080: 6e65 6374 696f 6e3a 204b 6565 702d 416c nection:.Keep-Al
0x0090: 6976 650d 0a0d 0a ive….
15:05:27.860678 ee:ff:ff:ff:ff:ff > 00:16:3e:04:af:53, ethertype IPv4 (0x0800), length 449: (tos 0x60, ttl 48, id 47418, offset 0, flags [DF], proto TCP (6), length 435)
220.181.112.244.80 > 139.129.205.48.53353: Flags [P.], cksum 0x6a94 (correct), seq 65362085:65362480, ack 2930938667, win 772, length 395
0x0000: 4560 01b3 b93a 4000 3006 e94e dcb5 70f4 E`…:@.0..N..p.
0x0010: 8b81 cd30 0050 d069 03e5 58a5 aeb2 932b …0.P.i..X….+
0x0020: 5018 0304 6a94 0000 4854 5450 2f31 2e31 P…j…HTTP/1.1
0x0030: 2032 3030 204f 4b0d 0a53 6572 7665 723a .200.OK..Server:
0x0040: 2062 6665 2f31 2e30 2e38 2e31 380d 0a44 .bfe/1.0.8.18..D
0x0050: 6174 653a 2054 6875 2c20 3237 204a 756c ate:.Thu,.27.Jul
0x0060: 2032 3031 3720 3037 3a30 353a 3237 2047 .2017.07:05:27.G
0x0070: 4d54 0d0a 436f 6e74 656e 742d 5479 7065 MT..Content-Type
0x0080: 3a20 7465 7874 2f68 746d 6c0d 0a43 6f6e :.text/html..Con
0x0090: 7465 6e74 2d4c 656e 6774 683a 2032 3338 tent-Length:.238

此时,httpry是一个很好的替代工具。使用httpry捕获上述请求,输出如下:

2017-07-27 15:08:50 139.129.205.48 220.181.112.244 > GET www.baidu.com / HTTP/1.0 – –
2017-07-27 15:08:50 220.181.112.244 139.129.205.48 < – – – HTTP/1.1 200 OK

简单明了。

  • 安装
    • 下载源码,make && make install就ok了
    • 这个程序依赖libpcap-devel库,没有的话就yum install -y libpcap-devel
  • 使用
    • 最简单的:httpry -i eth0
    • 支持过滤http请求方法:httpry -i eth0 -m GET
    • 支持保存抓包:httpry -i eth0 -o eth0-http.log
    • 可以指定packet filter:httpry -i eth0 ‘dst host www.baidu.com’
分类: 工具 标签: , , ,

shell中计算偏移日期的方法

2017年6月29日 没有评论

给定一个日期,如何在shell中计算前几天或者后几天的日期?

方法如下:

#给定当前日期
d1=`date +%F`

#计算两天后的日期
offset=2

 #d1转换成秒, since 1970-01-01 00:00:00 UTC
d1s=`date -d $d1 +%s`

#将偏移天数换算成秒数
offset_s=`expr 86400 \* $offset` 

#计算偏移后 的秒数
d2s=`expr $d1s + $offset_s`

#将偏移后的秒数转换成日期
d2=`date -d @$d2s + %F`

主要原理就是通过date -d +%s来实现日期和秒之间的互转,详情man date一下吧。

分类: Shell 标签: ,

wtail:可以多屏输出的多文件跟踪查看工具

2017年5月17日 没有评论

tail是我们常用到的文件跟踪查看工具,-n可以查看末尾n行,-f可以实时跟踪文件(描述符)的最新变化。当然也可以同时查看多个文件,但是多文件的输出是混杂在一起的,没那么直观。

现在好了,我们有了wtail。这是一个可以在同一个终端窗口中同时输出多个被跟踪文件数据的工具,每个文件可以在单独的小屏幕中输出,即一个窗口分屏输出。

  1. 安装
    • wtail依赖libncurses,某些机器上可能没有这个库,需要手动安装:

      wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz

      tar xzvf ncurses-6.0.tar.gz && cd ncurses-6.0

      ./configure && make && make install

    • 下载wtail源码包,解压,make && make install
  2. 使用
    • wtail *.log
分类: Shell, 工具, 运维 标签: , ,

使用rsync进行文件同步

2017年4月25日 没有评论
  1. rysnc是什么
    1. 这是一个linux平台上通用的文件同步工具,可以在本地目录或本地与服务器之间进行文件同步
    2. 安全:支持自定义端口,支持口令配置
    3. 高效:只传输差异部分,支持压缩传输
    4. 易用:支持通配符,支持exclude来排除特定文件
  2. 安装
    1. 大多数linux服务器默认安装有rsync
    2. 如果没有,简单运行yum -y install rsync就ok了
  3. 简单示例
    1. 同步的前提是两端服务器都安装了rsync
    2. push方式:rsync /localDir/file user@remoteServerAddress:/remoteDir
    3. pull方式:rsync user@remoteServerAddress:/remoteDir/file /localDir
    4. 上述两条命令实际上是通过ssh来通信的,所以如果对端服务器用户配置了密码的话需要输入密码
    5. rsync还支持通过rync协议来通信,有两种命令方式可以使用该协议
      1. 在服务器和路径之间使用双冒号,比如

        rsync /localDir/file user@remoteServerAddress::/remoteDir

      2. 显式使用,如

        rsync rsync://user@remoteServerAddress[:remoteServerPort]/remoteDir/file /localDir

  4. 以daemon方式配置和运行
    1. rsync可以在一端或者两端以daemon进程形式来运行,通过配置rsyncd.conf来定制同步业务
    2. 这里列举一个简单的配置文件/etc/rsyncd.conf:

      #global settings
      pid file = /var/rsync/rsync.pid
      port = 873
      lock file = /var/rsync/lock.log
      log file = /var/rsync/rsync.log

      #module settings
      [SyncFiles]
      path=/data/files/
      use chroot = no
      max connections = 5
      read only = yes
      write only = no
      list = no
      uid = nobody
      gid = nobody
      incoming chmod = 644
      auth users = syncUser
      secrets file = /etc/rsync.pass
      strict modes = yes
      hosts allow = 192.168.1.119
      hosts deny = *
      ignore errors = yes
      timeout = 120

    3. 授权文件/etc/rsync.pass格式

      syncUser:_password_

    4. 注意事项:需要chmod 600 /etc/rsync.pass
    5. 启动进程:rsync –daemon,可将此命令加入/etc/rc.local
    6. 客户端同步命令:

      rsync -az –password-file=./sync_auth rsync://syncUser@remoteServerAddress[:remoteServerPort]/SyncFiles/* /localDir

    7. 由于同步用户配置了权限,客户端每次rsync操作都需要输入密码,可以通过–password-file选项来指定密码文件,这样就可免去输入密码了,如上面命令所示。该密码文件的格式很简单,单行文本写入密码即可,同样需要chmod 600 ./sync_auth
  5. 检测文件是否需要同步
    1. -i参数:可以对对端文件的变更进行摘要,据此可以判断是否需要同步
    2. -n参数:尝试同步操作但不传输文件
    3. 结合起来,-in就可以根据输出来判断是否需要同步了
  6. 其他:
    1. –delete参数支持删除文件的同步
    2. -L支持软链接目标目录的同步
    3. 如果写入的目录没有权限,会报以下错误,执行chown -R nobody.nobody /data/files/修改权限即可解决

      rsync: mkstemp failed: Permission denied (13)

分类: Shell, 运维 标签: , , ,

Redis低版本无法向前兼容高版本RDB文件

2016年9月26日 没有评论

今天做了一个操作导致Redis无法启动。

在部署某一程序的过程中,先是单独安装了3.2.3版本的redis,安装完成后ps一下,redis已经启动。然后又使用安装包部署程序,安装包中包含一个2.8.13版本的redis,直接把之前装的3.2.3的redis给覆盖掉了。程序安装完成后发现redis进程没了,而且通过service redis_6379 restart无法启动。

怎么回事?查看/var/log/redis_6379.log发现如下错误:

[31934] 26 Sep 11:31:47.087 # Can’t handle RDB format version 7
[31934] 26 Sep 11:31:47.087 # Fatal error loading the DB: Invalid argument. Exiting.

哦,当前版本的redis无法处理version=7的RDB格式,这才明白是兼容性问题,但这种“向前兼容”一般很难做到的。

解决办法:删除rdb文件/var/lib/redis/6379/dump.rdb,重启redis就行了。

2017.11.08:今天在redis官网上看到一篇文章,是介绍redis rdb文件版本历史的,参这里。详细介绍了各版本的演进历史,并说明了高版本rdb文件回退到低版本的方法,有需要的朋友可以了解一下。

分类: Redis, 运维 标签: ,

linux下制作二进制 bin文件

2016年3月24日 没有评论

制做方法是使用cat 命令将执行脚本和打包文件同时放到一个.bin的文件里。这样安装的时候只要使用一个包,直接执行该包即可安装完毕,简单方便。
例:制作安装apache、mysql的安装脚本包
1.将源码包先打包
#tar zcvf packages.tar.gz httpd-2.0.63.tar.bz2 mysql-5.0.33.tar.gz

2.编写脚本如下:
# cat install.sh
#!/bin/bash
dir_tmp=/root/installapache
mkdir $dir_tmp
sed -n -e ‘1,/^exit 0$/!p’ $0 > “${dir_tmp}/packages.tar.gz” 2>/dev/null
cd $dir_tmp
tar zxf packages.tar.gz
tar jxf httpd-2.0.63.tar.bz2
cd  httpd-2.0.63
./configure –prefix=/tmp/apache2
make
make install
cd $dir_tmp
tar zxf mysql-5.0.33.tar.gz
cd mysql-5.0.33
./configure –with-charset=gbk –with-extra-charsets=binary,latin1,gb2312 –localstatedir=/home/db –with-mysqld-ldflags=-all-static -enable-assembler –with-innodb –prefix=/tmp/mysql5
make
make install
exit 0

#cat install.sh packages.tar.gz >install.bin

这样就生成install.bin的安装文件,该文件是由shell脚本和二进制合成的。前半部分是脚本后半部分是二进制文件,用strings等二进制查看命令可以看到。
最主要的是下面这句,是将二进制文件从.bin文件里分离出来
sed -n -e ‘1,/^exit 0$/!p’ $0 > “${dir_tmp}/packages.tar.gz” 2>/dev/null

安装的时候直接执行
sh install.bin
安装这个方法可以将我们平时常使用的安装脚本化,然后打包。以后使用就方便了。

 

分类: Shell, 运维 标签: , ,

查找linux大文件

2016年2月18日 没有评论

cd path_to_be_searched;

du -sh *

du可以快速统计指定目录下文件的大小,-s选项可汇总子目录所占的磁盘空间。

Linux的优点就是在于有这么多实用工具,让看似复杂的事情,一条命令就可以解决。

分类: Shell, 监控 标签: ,

修改ssh端口的方法及相关事项

2015年12月30日 没有评论
  1. ssh的配置文件为/etc/ssh/sshd_config ,其中的Port即是开放端口,这一行默认是注释掉的。去掉注释,并改成其他端口
  2. 远程修改ssh端口是风险较高的操作,可能会导致无法连上服务器,原因在于系统防火墙可能不允许要更改的端口
  3. 较安全的修改流程为:
    • 去掉sshd_config中默认Port行前边的注释,并新加一个拷贝行,在新加行配置想要更改的端口
    • 在防火墙中添加规则,放行要更改的ssh端口,重启防火墙
    • 重启ssh,尝试使用新端口登录ssh
    • 新端口登录ssh成功,在sshd_config中重新打开默认Port行的配置,并重启ssh
  4. 可能会被扫描和攻击,检测方法为查看系统日志/var/log/secure。如果被非法扫描或攻击,该日志文件会提示扫描ip及频繁登录失败的信息。在防火墙中禁止扫描ip即可。
分类: 安全 标签: ,

磁盘空间不足导致redis无法正常运行

2015年12月21日 没有评论

如果redis配置了后台存盘操作(配置文件中开启了save选项),并且redis运行内存占用较大,若系统磁盘空间不足,会导致redis无法正常运行。后台报错如下:

(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

所以,线上系统不仅要监控redis内存使用情况,也需要关注磁盘使用情况!

分类: Redis, 监控, 资料 标签: ,