shell下定时监测程序的死锁

这几天在处理微博爬虫。由于各种原因,爬虫经常为会出现网络错误断开连接,有时莫名其妙的程序锁死(程序在运行,但其实没有任何输出结果显示在运行)。因此就产生了一个定时检查所运行脚本的脚本,或者就在脚本中定时检查。但又不能将检测程序放入cron中,因为程序kill掉后还要继续向前运行。

处理方法如下:
1. 爬虫脚本将结果输出到某log文件中
2. 若log文件在一定时间内未发生变化,而且爬虫脚本还在运行,那可以认定此时程序锁死。
3. 处理锁死程序,直接kill掉,然后继续时间循环。

脚本运用了pgrep(获取某运行程序的pid)、pkill(杀死某程序)。

#!/bin/bash

#only works in Linux shell
startdate='2016-07-03'
for i in {0..7};do
echo "Running time:"`date`
tododate=`date -d "${startdate} $i days" +%Y-%m-%d`
logfile="weibo-${tododate}.log"
python -u weibo-num.py $tododate >$logfile 2>&1 &
while sleep 120;do
cmd=`pgrep -f "weibo-num.py ${tododate}"`
delta=$((`date +%s`-`date -r $logfile +%s`))
if [ ! -z $cmd ] && [ $delta -ge 900 ];then
pkill -f "weibo-num.py ${tododate}"
break
elif [ -z $cmd ]; then
break
fi
done
done

shell下python脚本的输出转向

一个用python写的脚本,在本地测试的时候用python的print输出了一些状态信息,用于观测程序运行的状况。脚本自身比较耗时(中间故意设置了延时)。
在部署到服务器上后,需要后台运行,因此就想当然的转向输出到一个文本log中:
python script.py > output.log &
结果发现log文件一直是空白(程序在持续运行中),但正常应该是有文本记录的。结果网上搜索才发现,python脚本默认是在脚本整个执行完成后才输出的。(参考:https://unix.stackexchange.com/questions/182537/write-python-stdout-to-file-immediately/182542#182542
当然,知道问题后解决方案也很简单:
python -u script.py > output.log &

两台服务器的缺失数据同步

一台主服务器上的部分数据文件缺失,需要在另一台备份服务器上拷贝回来,但不想使用rsync进行全局同步,因此就需要对缺失文件进行直接处理。
但文件数量比较少的时候,直接scp回来即可,但数量较多的时候,就不能人工处理了,需要使用shell脚本处理:
1. 生成缺失文件列表,如mis.txt
2. 让主服务器可以用key方式ssh到备份服务器上
3. 逐个文件导入:
while IFS='' read -r line ;do scp user@backup-server:/path/$line .; done < mis.txt

两台服务器皆为ubuntu环境。

macbook 12.2.2测试版外接samsung SyncMaster 2333显示器问题

在这个public beta版本之前,这台samsung SyncMaster 2333外接显示器工作正常,系统升级public beta后突然不认之前的分辨率(1920X1080),变成13.9吋800X600的显示器,Scaled模式也只能到1280X1024分辨率了。
不能认识,于是注册了feedback账号作为bug汇报,但在public beta2版本时此问题依然未解决。

今天突然在stackexchange上搜索到了一个可用的方案,大喜,记录之:

You can go to System Preferences > Displays, then option-click (press option key while left-clicking) on Scaled to expose additional resolutions that aren’t exposed with a normal left-click.

虽然这种模式的1920X1080不是全屏(有小部分黑边),但比之前的模式大好!

–update: public beta3 解决了这个问题,看来feedback还是有作用的。

使用AWK过滤数据

现有大批量的文本数据,需要截取其中符合一定范围的数据(减少数据量)。数据的格式如下:

42.69,-84.6,1
41.74,-86.21,1
42.26,-83.73,2
43.01,-83.68,6
42.74,-84.48,3
42.29,-83.7,4
42.29,-83.25,2
41.36,-82.07,1
42.99,-83.73,3
42.24,-84.41,1

其中,截取的目标范围是第一列的数字在一定范围,如40-44,第二列在另个范围。
开始我是将其全部导入到数据库中(copy命令),然后再进行delete操作,但随数据的处理,数据库的速度越来越慢,导致数据的处理速度不可接受。因此想在入库前就先行截取。Google后发现了解决方案:Using AWK to Filter Rows
具体解决方案如下:
awk -F',' '{ if($1 <= 44.0 && $1>=41.0 && $2<=-82.0 && $2>=-87.0) {print }}' 20161026-2300-point.csv

数据巧处理:重复数据的合并处理

要处理一批数据,形式为:
lat,lon,num
每个文件有一个timestamp,文件数量巨大,开始我感觉lat、lat应该唯一,但后来检查数据后发现,这批数据存在大量重复的点(可能之前高精度数据是唯一的,但精度降低后导致有重复数据出现),因此需要专门处理。
开始是想在bash里直接处理,但点位相同的数据,其后的num感觉应该sum后替换,因此还没有想到较好的方法。
后来一想数据不是要入库么,入库后先放松唯一性检查,然后通过group操作,可以简单获取到对应的结果。
SQL:
create table sum_point as
select ts,lat,lon,sum(num) from point group by ts,lat,lon

linux下进入乱码目录

若一个目录在用户上传后是乱码,如何进入此目录呢?

1. 若首字母是英文或数字,可以输入首字母后通过tab补齐方式进入。

2. 可通过inode更名方式进入:

使用inode,重新命名。
$ ls -i1
获取inode是多少
$ find -inum $inode -exec mv {} $new_file_name \;
使用find命令重新命名,其中$inode是上一步ls获取到的数字,$new_file_name是新的文件名。

3. 可以通过mc命令菜单式进入(最简单直接)。

遭遇chipset heat sink not detected问题

我使用的一台DELL T7400工作站,在一次远程重启后彻底趴窝了。到办公室后,发现系统在自检的时候就无法通过,提示:

chipset heat sink not detected

在网上搜索到一个最相关的文章:
http://www.chinafix.com/thread-70694-1-1.html
提示是散热器的问题。
首先拆机器,鼓风机除尘,看看有没有解决的可能,但无解。
继续拆CPU风扇,感觉没有问题,但也重新更换硅胶,依旧无解。
最后发现在主板上还有一个散热风扇,而且其风扇的固定脚断了一根,但风扇本身很牢固,估计是主板的自检程序是根据固定脚的简单电路进行检查,尝试使用一个回形针直接插上。搞定!

感谢李大侠的帮助。

基于ibdata1的mysql数据库恢复

服务器的阵列坏掉后,数据恢复公司进行了抢救后,大部分数据都恢复回来。但MYSQL数据库发现仅恢复了部分数据,即部分数据库是完整的,其他的库仅恢复了空表。其中有一个很大的文件,即ibdata1,约200多GB,估计可以用来恢复数据库。

网上搜索后,发现是可行的,处理方法如下:

1. 在一台新机器上搭建相同的系统环境,包括一个全新的mysql环境。
2. 停止mysql服务。即sudo service mysql stop
3. 将恢复后的ibdata1、ib_logfile*文件拷贝到新机器的/var/lib/mysql/目录下,覆盖之前的文件。同时修改/etc/mysql/my.cnf文件,在mysqld部分添加:
[mysqld]
innodb_force_recovery = 6

4. 拷贝需要恢复的数据库文件(空表,即包括*.frm文件的目录)到新机器的/var/lib/mysql/目录下
5. 重启mysql服务,即sudo service mysql start,然后用mysql命令检查数据是否有恢复。若能恢复回来,则可以用mysqldump进行备份导出。