几个Shell脚本的例子,觉得还不错。
【例子:001】判断输入为数字,字符或其他
- #!/bin/bash
- read -p "Enter a number or string here:" input
- case $input in
- [0-9]) echo -e "Good job, Your input is a numberic! \n" ;;
- [a-zA-Z]) echo -e "Good job, Your input is a character! \n" ;;
- *) echo -e "Your input is wrong, input again! \n" ;;
- esac
【例子:002】求平均数
- #!/bin/bash
- # Calculate the average of a series of numbers.
- SCORE="0"
- AVERAGE="0"
- SUM="0"
- NUM="0"
- while true; do
- echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;
- if (("$SCORE" < "0")) || (("$SCORE" > "100")); then
- echo "Be serious. Common, try again: "
- elif [ "$SCORE" == "q" ]; then
- echo "Average rating: $AVERAGE%."
- break
- else
- SUM=$[$SUM + $SCORE]
- NUM=$[$NUM + 1]
- AVERAGE=$[$SUM / $NUM]
- fi
- done
- echo "Exiting."
【例子:003 】自减输出
- [scriptname: doit.sh]
- while (( $# > 0 ))
- do
- echo $*
- shift
- done
- /> ./doit.sh a b c d e
- a b c d e
- b c d e
- c d e
- d e
- e
- # 人名列表
- # cat namelist
- Jame
- Bob
- Tom
- Jerry
- Sherry
- Alice
- John
- # 脚本程序
- # cat namelist.sh
- #!/bin/bash
- for name in $(cat namelist)
- do
- echo "name= " $name
- done
- echo "The name is out of namelist file"
- # 输出结果
- # ./namelist.sh
- name= Jame
- name= Bob
- name= Tom
- name= Jerry
- name= Sherry
- name= Alice
- name= John
- [root@host ~]# cat testfile.sh
- #!/bin/bash
- for file in test*.sh
- do
- if [ -f $file ];then
- echo "$file existed."
- fi
- done
- [root@host ~]# ./testfile.sh
- test.sh existed.
- test1.sh existed.
- test2.sh existed.
- test3.sh existed.
- test4.sh existed.
- test5.sh existed.
- test78.sh existed.
- test_dev_null.sh existed.
- testfile.sh existed.
- [root@host ~]# df -ih /tmp
- Filesystem Inodes IUsed IFree IUse% Mounted on
- /dev/mapper/vg00-lvol5
- 1000K 3.8K 997K 1% /tmp
- [root@host ~]# cat cover_disk.sh
- #!/bin/env bash
- counter=0
- max=3800
- remainder=0
- while true
- do
- ((counter=counter+1))
- if [ ${#counter} -gt $max ];then
- break
- fi
- ((remainder=counter%1000))
- if [ $remainder -eq 0 ];then
- echo -e "counter=$counter\tdate=" $(date)
- fi
- mkdir -p /tmp/temp
- cat < testfile > "/tmp/temp/myfile.$counter"
- if [ $? -ne 0 ];then
- echo "Failed to write file to Disk."
- exit 1
- fi
- done
- echo "Done!"
- [root@host ~]# ./cover_disk.sh
- counter=1000 date= Wed Sep 10 09:20:39 HKT 2014
- counter=2000 date= Wed Sep 10 09:20:48 HKT 2014
- counter=3000 date= Wed Sep 10 09:20:56 HKT 2014
- cat: write error: No space left on device
- Failed to write file to Disk.
- dd if=/dev/zero of=testfile bs=1M count=1
- [root@host ~]# cat hosts.allow
- 127.0.0.1
- 127.0.0.2
- 127.0.0.3
- 127.0.0.4
- 127.0.0.5
- 127.0.0.6
- 127.0.0.7
- 127.0.0.8
- 127.0.0.9
- [root@host ~]# cat readlines.sh
- #!/bin/env bash
- i=0
- while read LINE;do
- hosts_allow[$i]=$LINE
- ((i++))
- done < hosts.allow
- for ((i=1;i<=${#hosts_allow[@]};i++)); do
- echo ${hosts_allow[$i]}
- done
- echo "Done"
- [root@host ~]# ./readlines.sh
- 127.0.0.2
- 127.0.0.3
- 127.0.0.4
- 127.0.0.5
- 127.0.0.6
- 127.0.0.7
- 127.0.0.8
- 127.0.0.9
- Done
- [root@host ~]# cat regex.sh
- #!/bin/env sh
- #Filename: regex.sh
- regex="[A-Za-z0-9]{6}"
- if [[ $1 =~ $regex ]]
- then
- num=$1
- echo $num
- else
- echo "Invalid entry"
- exit 1
- fi
- [root@host ~]# ./regex.sh 123abc
- 123abc
- #!/bin/env bash
- #Filename: validint.sh
- validint(){
- ret=`echo $1 | awk '{start = match($1,/^-?[0-9]+$/);if (start == 0) print "1";else print "0"}'`
- return $ret
- }
- validint $1
- if [ $? -ne 0 ]; then
- echo "Wrong Entry"
- exit 1
- else
- echo "OK! Input number is:" $1
- fi
【例子:008】简单的按日期备份文件
- #!/bin/bash
- NOW=$(date +"%m-%d-%Y") # 当前日期
- FILE="backup.$NOW.tar.gz" # 备份文件
- echo "Backing up data to /tmp/backup.$NOW.tar.gz file, please wait..." #打印信息
- tar xcvf /tmp/backup.$NOW.tar.gz /home/ /etc/ /var # 同时备份多个文件到指定的tar压缩文件中
- echo "Done..."
【例子:009】交互式环境select的使用
- #!/bin/bash
- echo "What is your favorite OS?"
- select OS in "Windows" "Linux/Unix" "Mac OS" "Other"
- do
- break
- done
- echo "You have selected $OS"
- root@localhost:~/training# ./select.sh
- What is your favorite OS?
- 1) Windows
- 2) Linux/Unix
- 3) Mac OS
- 4) Other
- #? 1
- You have selected Windows
- #!/bin/bash
- # we have less than 3 arguments. Print the help text:
- if [ $# -lt 3 ]; then
- cat <<-EOF
- ren -- renames a number of files using sed regular expressions
- USAGE: ren.sh 'regexp' 'replacement' files
- EXAMPLE: rename all *.HTM files in *.html:
- ren 'HTM$' 'html' *.HTM
- EOF
- exit 0
- fi
- OLD="$1"
- NEW="$2"
- # The shift command removes one argument from the list of
- # command line arguments.
- shift
- shift
- # $* contains now all the files:
- for file in $*
- do
- if [ -f "$file" ]; then
- newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
- if [ -f "$newfile" ]; then
- echo "ERROR: $newfile exists already"
- else
- echo "renaming $file to $newfile "
- mv "$file" "$newfile"
- fi
- fi
- done
- root@localhost:~/training# ./ren.sh "HTML$" "html" file*.HTML
- renaming file10.HTML to file10.html
- renaming file1.HTML to file1.html
- renaming file2.HTML to file2.html
- renaming file3.HTML to file3.html
- renaming file4.HTML to file4.html
- renaming file5.HTML to file5.html
- renaming file6.HTML to file6.html
- renaming file7.HTML to file7.html
- renaming file8.HTML to file8.html
- renaming file9.HTML to file9.html
- #!/bin/bash
- for VAR1 in 1 2 3
- do
- for VAR2 in 0 5
- do
- if [ $VAR1 -eq 2 -a $VAR2 -eq 0 ]
- then
- break 2 # 退出第二重循环,亦即退出整个循环
- else
- echo "第一个变量:$VAR1 第二个变量:$VAR2"
- fi
- done
- done
- root@localhost:~/training# ./test.sh
- 第一个变量:1 第二个变量:0
- 第一个变量:1 第二个变量:5
【例子:012】/dev/tty在读取人工输入中的特殊作用
- #!/bin/bash
- # 用来验证两次输入的密码是否一致
- printf "Enter your passwd: " # 提示输入
- stty -echo # 关闭自动打印输入字符的功能
- read pwd1 < /dev/tty # 读取密码
- printf "\nEnter again: " # 再次提示输入
- read pwd2 < /dev/tty # 再读取一次以确认
- stty echo # 打开自动打印输入字符的功能
- if [[ "$pwd1" == "$pwd2" ]]; then # 对两次输入的密码进行判断
- echo -e "\nPASSWORD: the same"
- else
- echo -e "\nPASSWORD: not same"
- fi
- root@localhost:~/training# ./test.sh
- Enter your passwd:
- Enter again:
- PASSWORD: the same
【例子:013】/dev/null在脚本中的简单示例
- #!/bin/bash
- if grep /bin/bash $0 > /dev/null 2>&1 # 只关心命令的退出状态而不管其输出
- then # 对退出状态进行判断
- echo -e "/bin/bash in $0\n"
- else
- echo -e "/bin/bash not in $0\n"
- fi
- 脚本输出:
- root@localhost:~/training# ./test.sh
- /bin/bash in ./test.sh
【例子:014】构建自己的bin目录存放执行脚本,然后随便执行的简单示例
- $ cd # <span style="font-family:FangSong_GB2312;">进入家目录</span>
- $ mkdir bin <span style="font-family:FangSong_GB2312;"># 创建$HOME目录下自己的bin目录</span>
- $ mv test.sh bin # 将我们自己的脚本放到创建的bin目录下
- <span style="font-family:FangSong_GB2312;">$ </span>PATH=$PATH:$HOME/bin # 将个人的bin目录放到PATH<span style="font-family:FangSong_GB2312;">中
- $ test.sh # 现在就可以直接执行自己的脚本了</span>
【例子:015】将长句子中单词长度为5及以上的单词打印出来
- #!/bin/bash
- # filename: test.sh
- sentence="When you're attracted to someone it just means that your subconscious is attracted to their subconscious, subconsciously.
- So what we think of as fate, is just two neuroses knowing they're a perfect match."
- for word in ${sentence}
- do
- new=`echo $word | tr -cd '[a-zA-Z]'` # 去除句子中的 ,或者'
- len=${#new} # 求长度
- if [ "$len" -ge 5 ] # 再判断
- then
- echo $new
- fi
- done
- root@localhost:~# ./test.sh
- youre
- attracted
- someone
- means
- subconscious
- attracted
- their
- subconscious
- subconsciously
- think
- neuroses
- knowing
- theyre
- perfect
- match
【例子:016】根据输入的数据(年4位,月2位),来判断上个月天数
- #!/bin/bash
- get_last_day()
- {
- year=`expr substr $1 1 4`
- month=`expr substr $1 5 2`
- curr_month=`echo $month | tr -d '0'` # 去掉里面的0,方便后面计算
- echo "curr_month=$curr_month"
- last_month=`expr $curr_month - 1`
- case $last_month in
- 01|03|05|07|08|10|12|0)
- echo "上个月天数-->" 31 ;;
- 02)
- if [ `expr $year % 400` = 0 ] ; then
- echo "上个月天数-->" 29
- elif [ `expr $year % 4` = 0 ] && [ `expr $year % 100` != 0 ] ; then
- echo "上个月天数-->" 29
- else
- echo "上个月天数-->" 28
- fi ;;
- *)
- echo "上个月天数-->" 30
- esac
- }
- if [ $# -ne 1 ]; then
- echo "Usage: $0 201608"
- else
- get_last_day $1
- fi
- root@localhost:~/training# ./test.sh 201601
- 上个月天数--> 31
【例子:017】统计文件中每个单词出现的频率
- #!/bin/sh
- # 从标准输入读取文件流,再输出出现频率的前n,默认:25个单词的列表
- # 附上出现频率的计数,按照这个计数由大到小排列
- # 输出到标准输出
- # 语法: wf [n]
- tr -cs A-Za-z\' '\n' |
- tr A-Z a-z |
- sort |
- uniq -c |
- sort -k1,1nr -k2 |
- sed ${1:-25}q
- root@localhost:~/training# wf 10 < /etc/hosts | pr -c4 -t -w80
- 6 ip 1 1 archive 1 capable
- 3 ff 1 allnodes 1 are 1 cn
- 2 localhost 1 allrouters
- #!/bin/bash
- # 等待特定用户登录,每30秒确认一次
- # filename: wait_for_user_login.sh
- read -p "Ener username:-> " user
- while true
- do
- if who | grep "$user" > /dev/null
- then
- echo "The $user now logged in."
- break
- else
- sleep 30
- fi
- done
- root@localhost:~/shell# ./wait_for_user_login.sh
- Ener username:-> guest
- The guest now logged in.
- #!/bin/bash
- # 将标志变量设置为空值
- file= verbose= quiet= long=
- while [ $# -gt 0 ] # 执行循环直到没有参数为止
- do
- case $1 in # 检查第一个参数
- -f) file=$2
- shift ;; # 移位-f,使得结尾shift得到$2的值
- -v) verbose=true
- quiet= ;;
- -q) quiet=true
- verbose= ;;
- -l) long=true ;;
- --) shift
- break ;;
- -*) echo "$0: $1: unrecongnized option >&2" ;;
- *) break ;;
- esac
- done
- ~
- #!/bin/bash
- while IFS=: read user pwd pid gid fullname homedir shell # IFS作为列之间的分隔符号,read读取多个变量
- do
- printf "The user=%s homedir=%s\n" "$user" "$homedir" # 对文本中的行进行处理
- done < /etc/passwd # 读取文件
- # 第二种方式
- #!/bin/bash
- cat /etc/passwd |
- while IFS=: read user pwd pid gid fullname homedir shell
- do
- printf "The user=%s homedir=%s\n" "$user" "$homedir"
- done
- #!/bin/bash
- # 方式一
- find /root/shell -type d -print | # 寻找所有目录
- sed 's;/root/shell/;/tmp/shell/;' | # 更改名称,使用;作为定界符
- sed 's/^/mkdir -p /' | # 插入mkdir -p 命令
- sh -x # 以Shell的跟踪模式执行
- # 方式二
- find /root/shell -type d -print | # 寻找所有目录
- sed 's;/root/shell/;/tmp/shell/;' | # 更改名称,使用;作为定界符
- while read newdir # 读取新的目录名
- do
- mkdir -p $newdir
- done
- ~
【例子:022】发邮件给系统前10名磁盘用户,要求清理磁盘空间
- #!/bin/bash
- cd /home # 移动到目录的顶端
- du -s * | # 产生原始磁盘用量
- sort -nr | # 以数字排序,最高的在第一位
- sed 10q | # 在前10行之后就停止
- while read amount name # 将读取的数据分别作为amount, name变量
- do
- mail -s "disk usage warning" $name << EOF
- Gretings. You are one of the top 10 consumers of disk space
- on the system. Your home directory users $amount disk blocks.
- Please clean up unneeded files, as soon as possible.
- Thanks,
- Your friendly neighborhood system administrator.
- EOF
- done
- #!/bin/bash
- # passwd-to-mailing-list
- #
- # 产生使用特定shell的所有用户邮寄列表
- #
- # 语法: passwd-to-mailing-list < /etc/passwd
- # 删除临时性文件
- rm -rf /tmp/*.mailing-list
- # 从标准输入中读取
- while IFS=: read user passwd uid gid name home Shell
- do
- Shell=${Shell:-/bin/sh} # 如为空shell,指/bin/sh
- file="/tmp/$(echo $Shell | sed -e 's;^/;;' -e 's;/;-;g').mailing-list"
- echo $user, >> $file
- done
- root@localhost:~# vim passwd-to-mailing-list
- root@localhost:~# passwd-to-mailing-list < /etc/passwd
- root@localhost:~# cat /tmp/bin-bash.mailing-list
- root,
- test,
- user,
- root@localhost:~# cat /tmp/bin-sh.mailing-list
- libuuid,
- jerry,
【例子:024】变更目录时更新PS1
- #!/bin/bash
- cd()
- {
- command cd "$@" # 实际改变目录
- x=$(pwd) # 取得当前目录的名称,传递给变量
- PS1="${x##*/}\$ " # 截断前面的组成部分,指定给PS1
- }
- root$ # 最后输出,类似于这种,看不到目录的完整路径
【例子:025】根据XML文件中的license时间来判断是否过期
- <?xml version="1.0" encoding="gb2312"?>
- <license>
- <pos>中国,福建,福州市,鼓楼区</pos>
- <installid>123123</installid>
- <device>hdsas_base_3.0.0.2_16Q2_RC2</device>
- <id>_RC257971fe611f0</id>
- <hwid>f04c3d1eb4bf6113</hwid>
- <issuetime>2016-08-02 16:46:39</issuetime>
- <expired>30 days</expired>
- </license>
- 获得<issuetime>2016-08-02 16:46:39</issuetime>时间加上<expired>30 days</expired>
- 期限,得到时间减去系统当前时间,小于7天,显示license即将在几天后过期。
代码如下:
- #!/bin/bash
- CURR_TIME=$(date +'%Y%m%d')
- FILE_TIME=$(grep 'issuetime' hdlicense.xml | tr -d '[\-a-z<>/]' | awk '{print $1}')
- REAL_TIME=$(date -d "$FILE_TIME +30 days" +%Y%m%d)
- d1=$(date "+%s" -d "$REAL_TIME")
- d2=$(date "+%s" -d "$CURR_TIME")
- EXPI_TIME=$(((d1-d2)/86400))
- if [ "$EXPI_TIME" -lt "7" ]; then
- echo "你的license将在 $EXPI_TIME 天后过期!"
- fi
【例子:026】根据参数来判断是否要新创建目录
- #!/bin/bash
- DIR=$1
- if [ X"$DIR" = X"" ]; then
- echo "Usage: `basename $0` directory to create" >&2
- exit 1
- fi
- if [ -d $DIR ];then
- echo "The directory you create is exist."
- exit 0
- else
- echo "The $DIR does not exist, will create now."
- echo -n "Create it now? [y/n]"
- read ANS
- if [ X"$ANS" = X"y" -o X"$ANS" = X"Y" ];then
- mkdir $DIR > /dev/null 2>&1
- if [ $? !=0 ]; then
- echo "Error creating the direcory $DIR" >&2
- exit 1
- else
- echo "Create $DIR OK"
- exit 0
- fi
- fi
- fi
【例子:027】创建新目录,并将当前目录下的所有.txt文件拷贝到新目录中
- #!/bin/bash
- DIR=testdir
- THERE=`pwd`
- mkdir $DIR > /dev/null 2>&1
- if [ -d $DIR ]; then
- cd $DIR
- if [ $? = 0 ]; then
- HERE=`pwd`
- cp $THERE/*.txt $HERE
- else
- echo "Cannot cd to $DIR"
- exit 1
- fi
- else
- echo "Cannot create directory $THERE"
- exit 1
- fi
【例子:028】菜单显示小脚本
- #!/bin/bash
- USER=`whoami`
- HOST=`hostname -s`
- DATE=`date '+%d/%m/%Y'`
- help(){
- cat <<EOF
- -----------------------------------------------------
- User: $USER Host: $HOST Date: $DATE
- -----------------------------------------------------
- 1. List files in current directory
- 2. Use the vi editor
- 3. See who is on the system
- H. Help screen
- Q. Exit Menu
- -----------------------------------------------------
- Your Choice [1, 2, 3, 4, H, Q] >
- EOF
- }
- while :
- do
- help
- echo -n "Enter your choice: "
- read ANS
- case $ANS in
- 1) ls -lart ;;
- 2) vi ;;
- 3) who ;;
- H) help ;;
- Q) exit 0 ;;
- esac
- done
- #!/bin/bash
- error_info()
- {
- echo "$@ error, please check your input."
- exit 1
- }
- check_name()
- {
- NAME=`echo $1 | tr -d '[a-zA-Z]'`
- if [ X"$NAME" = X"" ];then
- return 0
- else
- return 1
- fi
- }
- while :
- do
- echo -n "Please Input your first name:"
- read F_NAME
- if check_name $F_NAME; then
- echo "Your First Name met the condition."
- break
- else
- echo "Wrong input, please enter again."
- fi
- done
- while :
- do
- echo -n "Please Input your last name:"
- read L_NAME
- if check_name $L_NAME; then
- echo "Your Last Name met the condition."
- break
- else
- error_info
- fi
- done
- ~