赞
踩
- #!/bin/sh
-
- # dtree: Usage: dtree [any directory]
-
- dir=${1:-.}
-
- (cd $dir; pwd)
-
- find $dir -type d -print | sort -f | sed -e "s,^$1,," -e "/^$/d" -e "s,[^/]*/([^/]*)$,`----1," -e "s,[^/]*/,| ,g"
-
-
2 while中使用read (file是一个文件)
cat file | while read line do echo $line echo " :: Please input any key(s):c" str4read="" while true do chr4read=`dd if=/dev/tty bs=1 count=1 2>/dev/null` str4read=$str4read$chr4read if [ "$chr4read" = "" ] ;then break; fi done echo " :: |$str4read|" done
3 将多个空格替换为字符
- sed 's/[ ][ ]*/ /g'
-
- 如果空格与tab共存时用
-
- sed -e 's/[[:space:]][[:space:]]*/ /g' filename
4用脚本实现分割文件
#!/bin/bash if [ $# -ne 2 ]; then echo 'Usage: split file size(in bytes)' exit fi file=$1 size=$2 if [ ! -f $file ]; then echo "$file doesn't exist" exit fi #TODO: test if $size is a valid integer filesize=`/bin/ls -l $file | awk '{print $5}'` echo filesize: $filesize let pieces=$filesize/$size let remain=$filesize-$pieces*$size if [ $remain -gt 0 ]; then let pieces=$pieces+1 fi echo pieces: $pieces i=0 while [ $i -lt $pieces ]; do echo split: $file.$i: dd if=$file of=$file.$i bs=$size count=1 skip=$i let i=$i+1 done echo "#!/bin/bash" > merge echo "i=0" >> merge echo "while [ $i -lt $pieces ];" >> merge echo "do" >> merge echo " echo merge: $file.$i" >> merge echo " if [ ! -f $file.$i ]; then" >> merge echo " echo merge: $file.$i missed" >> merge echo " rm -f $file.merged" >> merge echo " exit" >> merge echo " fi" >> merge echo " dd if=$file.$i of=$file.merged bs=$size count=1 seek=$i" >> merge echo " let i=$i+1" >> merge echo "done" >> merge chmod u+x merge'
5得到上月未日期,格式为YYYYMMDD
get_lastday_of_lastmonth() { yy=`date +%Y` mm=`date +%m-1|bc` [ $mm -lt 1 ] && mm=12;yy=`expr $yy - 1` aaa=`cal $mm $yy` dd=`echo $aaa|awk '{print $NF}'` echo $yy$mm$dd } print $NF的$NF是打印最后一个列。因为awk的内置变量NF是列的总数,而$NF就代表着最后一列
6 实现用backup或tar命令来做目录备份
需要保持两个目录当中的文件以及属组关系不变。子目录结构不变,通过管道控制tar和backup命令,不需要中间的archive,(考虑到速度以及空间的关系) (cd /source && tar cf - .) |(cd /dest && tar zxfp -) 偶没有 backup 命令,但是 tar 用管道可以, tar -cf - dir1 | ( cd dir2; tar -xvf - ) 搬移大法 more aaa.sh #计算两个日期间有多少天 #date1,date2:yyyymmdd #Usage:command date1 date2 str=$1 yy1=`echo $str|cut -c 1-4` mm1=`echo $str|cut -c 5-6` dd1=`echo $str|cut -c 7-8` str=$2 yy2=`echo $str|cut -c 1-4` mm2=`echo $str|cut -c 5-6` dd2=`echo $str|cut -c 7-8` count_day=`expr $dd2 - $dd1` while [ $yy2 -ne $yy1 -o $mm2 -ne $mm1 ] do mm2=`expr $mm2 - 1` [ $mm2 -eq 0 ] && mm2=12 && yy2=`expr $yy2 - 1` aaa=`cal $mm2 $yy2` bbb=`echo $aaa|awk '{print $NF}'` count_day=`expr $count_day + $bbb` done echo $count_day
7 编写一个只允许用户执行telnet的shell
- 为了监视用户网络操作行为,指定unxi主机给设备管理员登陆,然后用shell控制他。只可以使用telnet命令,其他一概不许,包括cd,ls等。就是一个用来远程登陆的管理平台。我对shell不熟,请指导。
-
- .profile中加入:
-
- read addr
-
- telnet $addr
-
- exit
8 判断文件的访问权限是不是600
ls -l filename | awk '{ if($1 ~ "-rw-------") ..... }' ls -l filename | grep "^-rw------" -c #!/usr/bin/bash #showmod [ $# -eq 0 ] && { echo "Usage: $0 filelist ... "; exit ;} show() { { [ -d $1 ] && ls -ld $1 ; [ -f $1 ] && ls -la $1 ;} | awk '{ umask=0 umask_="" for(i=1;i<length($1);i++) { if(substr($1,i+1,1)=="r") umask+=4; if(substr($1,i+1,1)=="w") umask+=2; if(substr($1,i+1,1)=="x") umask+=1; if(i%3==0) { umask_=sprintf("%s%d",umask_,umask); umask=0; } } printf("%-20.20s: %-10.10s --> %s ",$9,$1,umask_); }'; } for file_dir in $* do show $file_dir done
9 算青蛙的脚本
maxcount=$1; count=1; if [ $# -eq 1 ] then while [ $count -le $maxcount ] do echo $count 只青蛙 $count 张嘴, `expr $count * 2`只眼睛,`expr $count * 4`条腿; count=`expr $count + 1`; done; else echo "usage: sendos count" fi
10 在SHELL程序中实现‘按任意键继续’
在写一个SHELL程序,可是遇到了一个难题,在READ接受输入时,必须按回车键才能确认,而我需要只要按一个键就能得到用户的输入,无须按回车键!有什么好办法呢
#!/bin/sh get_char() { SAVEDSTTY=`stty -g` stty -echo stty raw dd if=/dev/tty bs=1 count=1 2> /dev/null stty -raw stty echo stty $SAVEDSTTY } echo "Press any key to continue..." char=`get_char` 如果你的机器上不认stty raw那么把函数中两处出现的raw换成cbreak。
11 在linux环境下启动时打开numlock
想在系统启动时自动打开NumLock,可以在/etc/rc.d/rc.local中加入以下内容:
- for t in 1 2 3 4 5 6 7 8
-
- do
-
- setleds +num
-
- $t>/dev/null
-
- done
12 在shell里如何限制输入的长度
举个例子,比如用户输入用户名时只能给他输入8个字符,如果超过了8个字符光标就停止在第八个字符那儿,不继续,一直等待回车只怕要自己来另写一个SHELL了。
我现在可以实现到如果输入超出的话光标就停在最后一个字符,但是对于那些输入小于规定位数的那些就没折了,举个例子,比如用户域最长不能超过8位,我输入了6位然后回车,就不会结束,一定要输入完8位按回车才可以结束
文件名: input.sh 用法:input.sh 限制的长度
例:input.sh 8 即限制输入8位。
#!/bin/ksh # Program Name : input.sh trap '' 1 2 3 5 7 9 15 13 getcon(){ stty raw -echo conchar=`dd if=/dev/tty bs=1 count=1 2>/dev/null` stty sane echo "$conchar" } while i=0;clear >/dev/tty echo "
13 双机(多机)自动互备份方案
问 题:
公司有两台LINUX服务器,每个服务器只有一个硬盘。所以备份的问题就显得特别重要。我们装有MySQL数据库。当然同时也要解决MySQL备份的问题。
目 的:
host 机器最终所有备份都在其上留备份,ship机器保存host机器备份
方 法:
通过shell脚本,打包相关要备份的文件。然后通过ftp操作下载,上载完成解决方案。
两台机器root 通过crontab 让脚本在各自机器定时执行。
建议host 每天早上3点执行。
建议ship 每天早上6点执行。
注意点:
两台服务器系统时间最好相差不要超过1小时。
此脚本是每周礼拜6执行备份的。当然你也可以修改成每月或每天备份。
当然也可以修改成一个增量备份脚本。
具体脚本:
以下为host机器脚本
#//host机器脚本/// #! /bin/sh HOST="abc.com" USER="backup_use" #ship机器backup_use用户 PASSWORD="backup_use" #ship机器对应用户密码 BACKUPDIR="/home/backup_use/ship" #host机器backup_use用户目录 BACKUPDIR2="/home/backup_use/host" #host机器backup_use用户目录 MYSQLPASS="abc" #ship 机器MySQL root 用户密码 PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/nusphere/MySQL/bin DOW=`date +%a` DM=`date +%Y%b%d` FILE1=ship-virtual-$DM.tar.gz FILE2=ship-MySQLdata-$DM.tar.gz FILE3=ship-szeasy-$DM.tar.gz FILE4=ship-other-$DM.tar.gz # FIL1=$BACKUPDIR2/host-main-$DM.tar.gz FIL2=$BACKUPDIR2/host-MySQLdata-$DM.tar.gz FIL3=$BACKUPDIR2/host-other-$DM.tar.gz # DIRECTORIE1="/www /home/jjd" # 要备份的目录1 DIRECTORIE2="/etc /var/named /usr/local/nusphere/apache/conf" # 要备份的目录2 # if [ $DOW = "Sat" ]; then # 每个礼拜六完全备份 tar -zcpf $FIL1 $DIRECTORIE1 tar -zcpf $FIL3 $DIRECTORIE2 MySQLdump --all-databases -q -uroot -p$MYSQLPASS |gzip > $FIL2 ftp -i -n < $BACKUPDIR/$COMPUTER-MySQLdata-$DM.tar.gz fi
14 文件序列a1,a2,a3...a11,a12...a1000改成a0001,a0002...a1000?
$cat test ls a* > tempfile1 sed 's/a//' tempfile1 > tempfile2 awk '{printf("mv a%s a%04s ", $0, $0)}' tempfile2 > tempfile3 chmod 700 tempfile3 ./tempfile3 rm tempfile* $chmod test ---------------------------------------------------------------- ls a*|awk '{ num=substr($1,2,length($1)-1); printf "mv %s a%04d ",$1,num }'>rename.sh sh rename.sh ---------------------------------------------------------------- for file in a* do newfile=`echo $file | awk '{printf "a%04d", substr($1, 2, length($1)-1)}'` mv $file $newfile done 给个不用awk的,效率会低一点 ls -1 a*|while read j do num=`echo $j|cut -b 2-` num=`printf a%04s $num` mv $j $num done ----------------------------------------------------------------- 稍微缩减一下: for file in a* do mv $file `echo $file|awk '{printf "a%04d", substr($1,2,length($1)-1)}'` done 如果a1,a2,a3...等文件是各自有不同的扩展名呢?就像a1.pxx,a2,baa,a3.tga... 这样是不是可以呢: for file in a* do nam=`echo $file|cut -d. -f1` exe=`echo $file|cut -d. -f2` mv $file `echo $nam|awk '{printf "a%04d", substr($1,2,length($1)-1)}'`.$exe done
15 禁止从一个IP登录的shell
解决方案0:
用shell完全可以解决,如果有tcpwrapper的系统,可以直接加/etc/hosts.deny
解决方案1:
在/etc/profile里加一段shell就可以了(sco openserver)
这是我写的只要求本C段登陆的shell,改改就可以了.
who=`who am i|awk '{print $1}'` myterm=`who am i|awk '{print substr($2,4,2)}'` if [ "x"$who = "xroot" ] then subnet=`finger|grep $myterm|awk '{print substr($8,1,8)}'` else subnet=`finger|grep $myterm|awk '{print substr($7,1,8)}'` fi test x$subnet != x && test x$who != xroot && test "x"$subnet != "x46.8.44." && echo " Please login from local network " && exit
16 eval用法三例
## shell:/bin/sh ## #例一: #寻找符合条件的变量名,然后将该变量的值赋予另一变量 v1=aaa v2=bbb c=1 if [ $c -eq 1 ] then vname=v$c #找到符合条件的变量名为v1 eval vvv="$"$vname ; echo vvv: $vvv #将变量v1的值赋予vvv,即,使vvv=aaa eval vvv='$'$vname ; echo vvv: $vvv #将变量v1的值赋予vvv,即,使vvv=aaa #eval vvv=$$vname ; echo vvv: $vvv #错误用法 fi
- #例二:#以变量v1的值aaa作为变量名,将变量vaaa的值赋予这一新定义的变量aaa
-
- v1=aaa ; vaaa="This is aaa"
-
- #eval $v1=$vaaa ; echo aaa: $aaa #错误用法
-
- #eval $v1="$vaaa" ; echo aaa: $aaa #错误用法
-
- eval $v1='$vaaa' ; echo aaa: $aaa
- #例三:
-
- #以变量v1的值aaa作为变量名,并将变量名字串作为值赋予自身
-
- v1=aaa ; vaaa="This is aaa"
-
- eval $v1=$v1 ; echo aaa: $aaa #与例二的错误用法不同,这一用法是正确的
-
- eval $v1="$v1" ; echo aaa: $aaa #与例二的错误用法不同,这一用法是正确的
-
- #区别在于,例二中的vaaa的值中间有空格
-
- eval $v1='$v1' ; echo aaa: $aaa
17 改变UNIX终端颜色
a. 用echo"<ctrl-v><escape>[31m测试<ctrl-v><escape>[37m"
echo "^[[Xm YourChar"
(X=30,31...36?)
请注意这个转义系列的敲法是,<ctrl-v><escape>[30m
echo "<ctrl-v><escape>[<代码>;<代码>;<代码>m"
注意,语句必须要在""之间,属性分隔符为";",如闪烁红色
echo "<ctrl-v><escape>[31;5m测试"
b. 前景 背景 颜色
---------------------------------------
30 40 黑色
31 41 紅色
32 42 綠色
33 43 黃色
34 44 藍色
35 45 紫紅色
36 46 青藍色
37 47 白色
代码 意义
-------------------------
0 OFF
1 高亮显示
4 underline
5 闪烁
7 反白显示
8 不可见
c. 产生颜色(黑色背景加绿色前景色):
sco: setcolor red; echo "abcd"; setcolorwhite
export PS1="[u@h W]$ "
19 grep/awk/sed的多条件查询
完!!!!
# cat gt one two three four five six one two one seven three # grep one three gt grep: three: No such file or directory gt:one two three gt:one two gt:one seven three 截取同时出现one和three的行,结果应该是: one two three one seven three a. 用grep cat gt | grep one | grep three b. 用awk awk '/one/&&/three/' gt c. 用sed sed -ne '/one/{/three/p}' gt
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。