shell递归一例

Posted by 4Aiur on 03/31/2010 in Shell with Comments closed |

用递归写的一个光标旋转的小脚本
[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

Tags:

数字的格式化打印

Posted by 4Aiur on 03/31/2010 in SysAdmin with Comments closed |

数字的格式化打印

有人问我一个产生"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

Tags:

统计squid下分频道cache文件总量

Posted by 4Aiur on 03/31/2010 in SysAdmin with Comments closed |

统计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是否压缩和编码的区别的话,会计算成多个。

Tags: ,

rsync模式匹配

Posted by 4Aiur on 03/31/2010 in SysAdmin with Comments closed |

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

Tags:

设置JAVA时区

Posted by 4Aiur on 03/31/2010 in Linux with Comments closed |

设置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时区有差异就是因为它们读取的配置文件不同。

Tags:

排除Apache access log乱序日志

Posted by 4Aiur on 03/31/2010 in Shell with Comments closed |

排除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)"

Tags: ,

带特殊字符文件的删除方法

Posted by 4Aiur on 03/31/2010 in Linux with Comments closed |

带特殊字符文件的删除方法

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-

Tags: ,

磁盘空间满故障排除

Posted by 4Aiur on 03/31/2010 in SysAdmin with Comments closed |

磁盘空间满故障排除

磁盘空间满一般情况下使用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查看磁盘空间使用率

  1. 删除的文件使用du无法查看
  2. 磁盘分区的某一个目录挂载了另外一个分区时,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

Tags: ,

自动修改crontab配置

Posted by 4Aiur on 03/31/2010 in Shell with Comments closed |

自动修改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 ~]$

Tags: ,

被用于保留(reserved meanings)的退出状态码

Posted by 4Aiur on 03/31/2010 in Shell with Comments closed |

 

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

According to the above table, exit codes 1 – 2, 126 – 165, and 255 have special meanings, and should therefore be avoided for user-specified exit parameters. Ending a script with exit 127would certainly cause confusion when troubleshooting (is the error code a “command not found” or a user-defined one?). However, many scripts use an exit 1 as a general bailout upon error. Since exit code 1 signifies so many possible errors, this probably would not be helpful in debugging.
There has been an attempt to systematize exit status numbers (see /usr/include/sysexits.h), but this is intended for C and C++ programmers. A similar standard for scripting might be appropriate. The author of this document proposes restricting user-defined exit codes to the range 64 – 113 (in addition to 0, for success), to conform with the C/C++ standard. This would allot 50 valid codes, and make troubleshooting scripts more straightforward.
All user-defined exit codes in the accompanying examples to this document now conform to this standard, except where overriding circumstances exist, as in Example 9-2.
Issuing a $? from the command line after a shell script exits gives results consistent with the table above only from the Bash or sh prompt. Running the C-shell or tcsh may give different values in some cases.

Notes

Out of range exit values can result in unexpected exit codes. An exit value greater than 255 returns an exit code modulo 256. For example, exit 3809 gives an exit code of 225 (3809 % 256 = 225).

Tags:

Copyright © 2010-2024 4Aiur All rights reserved.
This site is using the Desk Mess Mirrored theme, v2.5, from BuyNowShop.com.