shell递归一例
用递归写的一个光标旋转的小脚本
[root@maint-app-108 recurse]# cat cursor.sh
cursor () { #{{{
message="$1"
count="$2"
for item in "|" "/" "-" "\\"
do
printf "\r${item} ${message} $count"
usleep 50000
done
cursor waiting $((count+1))
}
cursor waiting 1
[root@maint-app-108 cursor]# 用递归做这种无限循环最后脚本会退出,下面这个while :不会退出。 [root@maint-app-108 cursor]# cat cursor.sh
cursor () { #{{{
message="$1"
for item in "|" "/" "-" "\\"
do
printf "\r${item} ${message}"
usleep 50000
done
}
while :
do
cursor waiting
done
数字的格式化打印
数字的格式化打印
有人问我一个产生"01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20"这样一种字符串的方法,当时我随意的写了一个
for ((x=1;x
我当时觉得有点土,之后人家问了如果打印的结果是从0到100怎么办呢?
因为最近买了本python的书,在复习pyhon的基础知识,恰好在看格式胡print的时候看到print%0是用0替换空格来占位,当时看书的时候感到有点怪,不知道数字前面加0有什么用,所以还有点印象。
所以像下面的python语句那么写好看多了。
Python 2.6.2 (r262:71600, Jul 2 2009, 16:30:16)
[GCC 3.4.4 20050721 (Red Hat 3.4.4-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> for x in range(20): print "%02d" %x,
...
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
>>>
之前printf用的很少,但是也清楚shell的格式化打印也是C的printf like的,今天到公司后试了下printf,确实可以work。
for ((x=1;x
bash 4的新功能
[4aiur@FreeBSD ~]$ bash --version
GNU bash, version 4.0.33(0)-release (i386-portbld-freebsd8.0)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
C
#include
int main(void){
int x;
for (x = 0; x
shell
seq -w 1 20
seq -f '%02g' 1 20
统计squid下分频道cache文件总量
统计squid下分频道cache文件总量
今天有个朋友问我怎么查看squid下分频道的cache文件总量
想了想用下面的命令实现起来方便又快捷,^_^
strings swap.state | \
awk -F"/" /^http/'{if ($3 in host) host[$3]++; else host[$3]=1}END{for (item in host) print item,host[item] | "sort -k2 -nr"}'
同一个url是否压缩和编码的区别的话,会计算成多个。
rsync模式匹配
rsync模式匹配
今天有一个同步数据的小问题,需要把一些符合特定日期的文件保存到另外一个目录,使用shell也很容易实现,之前没用rsync做过,今天顺便研究了一下rsync的实现方式,rsync是使用排除和取消排除的方法(诡异)。
为了实现递归,先写一个不排除的规则–include="*/"
再写一个希望保存文件的规则–include="2009022[78]"
最后写上排除所有的规则–exclude="*"
组合以上3个选项实现了对特定文件的同步。
rsync -aruv --include="*/" --include="*2009022[78]*" --include="*2009030[12]*" --exclude="*" /source /destination
# aruv比较常用
-a, --archive archive mode, equivalent to -rlptgoD
-r, --recursive recurse into directories
-u, --update update only (don't overwrite newer files)
-v, --verbose increase verbosity
设置JAVA时区
设置JAVA时区
RadHat上面运JDK,其获取时区的配置文件是/etc/sysconfig/clock。
# cat /etc/sysconfig/clock
ZONE="Asia/Shanghai"
UTC=false
ARC=false
昨天遇到了一个很怪异的现象。
现象是java程序输出的时间和系统时间相差了13个小时,与http://www.javaeye.com/topic/173077现象相同。
使用data命令查看系统时区是CST,但是执行java程序输出的取是"America/New_York"
使用timeconfig重新设置系统时区后,java获取到的时区恢复正常。
看了下timeconfig的manual,发现这个命令配置两个文件,分别是/etc/sysconfig/clock、/etc/localtime。
data命令输出的时区与java时区有差异就是因为它们读取的配置文件不同。
排除Apache access log乱序日志
排除Apache access log乱序日志
由于Apache的访问日志时间记录的是访问开始时间,所以会有时间不是顺序排列的情况产生。
由于有一个特殊需求,需要把乱序的日志排除掉,今天写了个小脚本处理了一下。
转换Apache accesslog时间为时间戳,进行处理
把乱序日志打印到了badlog文件中
[root@4Aiur ~]# cat foo
58.59.23.18 - - [26/Nov/2008:11:04:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
58.59.23.18 - - [26/Nov/2008:11:03:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
58.59.23.18 - - [26/Nov/2008:11:05:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
[root@4Aiur ~]# cat foo.awk
#!/bin/awk
function date2unixstamp(date) {
sub(/\[/,"",date)
split(date,array,/[/:]/)
if (array[2]=="Nov") array[2]="11"
else if (array[2]=="Jan") array[2]="01"
else if (array[2]=="Feb") array[2]="02"
else if (array[2]=="Mar") array[2]="03"
else if (array[2]=="Apr") array[2]="04"
else if (array[2]=="May") array[2]="05"
else if (array[2]=="Jun") array[2]="06"
else if (array[2]=="Jul") array[2]="07"
else if (array[2]=="Aug") array[2]="08"
else if (array[2]=="Sep") array[2]="09"
else if (array[2]=="Oct") array[2]="10"
#else if (array[2]=="Nov") array[2]="11"
else if (array[2]=="Dec") array[2]="12"
Time=array[3]" "array[2]" "array[1]" "array[4]" "array[5]" "array[6]" "array[7]
Timestamp=mktime(Time)
return Timestamp
}
{
date=$4
date2unixstamp(date)
#print date,Timestamp,temp,Time
if (Timestamp "badlog"
else {
print $0 > "accesslog"
temp=Timestamp
}
}
[root@4Aiur ~]# awk -f foo.awk foo
[root@4Aiur ~]# cat accesslog
58.59.23.18 - - [26/Nov/2008:11:04:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
58.59.23.18 - - [26/Nov/2008:11:05:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
[root@4Aiur ~]# cat badlog
58.59.23.18 - - [26/Nov/2008:11:03:05 +0800] "GET /test.html HTTP/1.1" 200 8228 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
带特殊字符文件的删除方法
带特殊字符文件的删除方法
list文件列表的时候发现有个"?"文件,直接删除?是删不掉的。
~]# ll
total 75040
-rw-r--r-- 1 root root 0 Nov 7 14:46 ?
# 使用cat -A 查看这个文件是带有特殊字符的文件
~]# ll | cat -A
total 75040$
-rw-r--r-- 1 root root 0 Nov 7 14:46 M-
磁盘空间满故障排除
磁盘空间满故障排除
磁盘空间满一般情况下使用du可以快速定位到那个目录占用了大量的磁盘空间。
这里主要讲两个使用du无法查看的情况。
现象/mnt分区磁盘使用率达到100%
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 97G 1.5G 90G 2% /
/dev/sda1 190M 12M 169M 7% /boot
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda3 97G 6.3G 85G 7% /usr
/dev/sda6 191G 408M 181G 1% /var
tmpfs 300M 300M 0 100% /mnt
/dev/loop0 190M 106M 74M 60% /mnt/foo
进入/mnt目录使用du查看/mnt下的磁盘使用率
# cd /mnt
# du -sh *
101M bar
101M foo
troubleshooting
解决思路
有两种情况会干扰du查看磁盘空间使用率
- 删除的文件使用du无法查看
- 磁盘分区的某一个目录挂载了另外一个分区时,du查看到的磁盘空间为挂载分区后的目录空间。
在了解上面两种情况后,解决这个问题会比较简单。
在生产环境中某一程序的日志文件被删除这一情况发生的几率会大些。
故障排除
# 1、查找被删除文件
# 被删除文件,在写程序未退出的情况下,被删除文件同样会占用磁盘空间。
# lsof -n | head -1
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# lsof -n /mnt | grep deleted
foo.sh 32593 root 1w REG 0,18 104538112 981982 /mnt/test.out (deleted)
foo.sh 32593 root 2w REG 0,18 104538112 981982 /mnt/test.out (deleted)
# 杀掉写文件的程序,磁盘空间会自然释放
# kill 32593
# df -h /mnt
Filesystem Size Used Avail Use% Mounted on
tmpfs 300M 201M 100M 67% /mnt
# 2、查看分区挂载情况
# 因为分区的目录下挂载有其它分区,被挂载分区的目录本身容量无法被查看,所以umount掉挂载分区的目录后将可正常查看此目录下文件所占用的容量。
# cd /mnt
# du -sh *
101M bar
101M foo #此容量为目录挂载分区后的新分区容量
# umount /mnt/foo
# du -sh *
21M bar
201M foo #此容量为目录所占用磁盘满分区的容量
测试环境搭建过程
# 挂载300M的内存tmpfs到/mnt目录
# mount -t tmpfs -o size=300m tmpfs /mnt
# cd /mnt && mkdir foo bar
# 先生成两个文件到foo bar下,占用一定的磁盘空间
# dd if=/dev/zero of=foo/file.out bs=1M count=100
# dd if=/dev/zero of=bar/file.out bs=1M count=100
# 查看磁盘当时的使用情况
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 97G 1.5G 90G 2% /
/dev/sda1 190M 12M 169M 7% /boot
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda3 97G 6.3G 85G 7% /usr
/dev/sda6 191G 408M 181G 1% /var
tmpfs 300M 201M 100M 67% /mnt
# 使用空文件建立一个文件系统
# cd /root/shell
# 生成200M的空文件
# dd if=/dev/zero of=foo.img bs=1M count=200
# 建立一个loop devices
# losetup /dev/loop0 foo.img
# 在loop devices上创建一个ext3文件系统
# mke2fs -j -c /dev/loop0 200000
# 使用/mnt/foo目录挂载/dev/loop0
# mount -t ext3 /dev/loop0 /mnt/foo
# 在/mnt/foo/目录产生一个测试文件file.out
# dd if=/dev/zero of=/mnt/foo/file.out bs=1M count=100
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 97G 1.5G 90G 2% /
/dev/sda1 190M 12M 169M 7% /boot
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda3 97G 6.3G 85G 7% /usr
/dev/sda6 191G 408M 181G 1% /var
tmpfs 300M 201M 100M 67% /mnt
/dev/loop0 190M 106M 74M 60% /mnt/foo
# /mnt/foo目录挂载方式伪装已经完成
# 删除文件伪装
# 编写一个死循环产生测试文件
# cat /root/shell/foo.sh
#!/bin/bash
# set -x
foo=$(seq 1 500)
while :
do
echo $foo
done
# 生成一个测试文件test.out占用/mnt目录的空间
# nohup /root/shell/foo.sh >/mnt/test.out 2>&1 &
# 删除测试文件
# \rm /mnt/test.out
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 97G 1.5G 90G 2% /
/dev/sda1 190M 12M 169M 7% /boot
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda3 97G 6.3G 85G 7% /usr
/dev/sda6 191G 408M 181G 1% /var
tmpfs 300M 300M 0 100% /mnt
/dev/loop0 190M 106M 74M 60% /mnt/foo
自动修改crontab配置
自动修改crontab配置
方法1:使用crontab -l把crontab内容导出到文件中,使用编辑器或脚本修改导出的文件,之后使用新的配置文件覆盖掉现有的配置。
[4Aur@4Aiur ~]$ crontab -l > cron[4Aur@4Aiur ~]$ sed -i 's/ls/dir/' cron
[4Aur@4Aiur ~]$ crontab cron
方法2:使用here文档的方式更新crontab的配置。
[4Aur@4Aiur ~]$ crontab -l0 * * * * ls
[4Aur@4Aiur ~]$ sh cron_modify.sh
[4Aur@4Aiur ~]$ crontab -l
0 * * * * dir
[4Aur@4Aiur ~]$ cat cron_modify.sh
crontab -e /dev/null
:%s/ls/dir/g
:wq
EOF
[4Aur@4Aiur ~]$
被用于保留(reserved meanings)的退出状态码
Exit Codes With Special Meanings
Reserved Exit Codes
Exit Code Number | Meaning | Example | Comments |
---|---|---|---|
1 | Catchall for general errors | let “var1 = 1/0” | Miscellaneous errors, such as “divide by zero” |
2 | Misuse of shell builtins (according to Bash documentation) | ? | Seldom seen, usually defaults to exit code 1 |
126 | Command invoked cannot execute | ? | Permission problem or command is not an executable |
127 | “command not found” | ? | Possible problem with $PATH or a typo |
128 | Invalid argument to exit | exit 3.14159 | exit takes only integer args in the range 0 – 255 (see footnote) |
128+n | Fatal error signal “n” | kill -9 $PPID of script | $? returns 137 (128 + 9) |
130 | Script terminated by Control-C | ? | Control-C is fatal error signal 2, (130 = 128 + 2, see above) |
255* | Exit status out of range | exit -1 | exit takes only integer args in the range 0 – 255 |