您的位置:首页 > 运维架构 > Shell

几个不错的Shell脚本

2017-03-27 14:22 288 查看
几个Shell脚本的例子,觉得还不错。

例子:001】判断输入为数字,字符或其他

[plain] view
plain copy

print?





#!/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】求平均数

[plain] view
plain copy

print?





#!/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】自减输出

[plain] view
plain copy

print?





[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

例子:004】在文件中添加前缀

[plain] view
plain copy

print?





# 人名列表

# 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

例子:005】批量测试文件是否存在

[plain] view
plain copy

print?





[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.

例子:005】用指定大小文件填充硬盘

[plain] view
plain copy

print?





[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

例子:006】通过遍历的方法读取配置文件

[plain] view
plain copy

print?





[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

例子:007】简单正则表达式应用

[plain] view
plain copy

print?





[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】简单的按日期备份文件

[plain] view
plain copy

print?





#!/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的使用

[plain] view
plain copy

print?





#!/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

例子:010】批量修改文件名的脚本

[plain] view
plain copy

print?





#!/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

例子:011】break语句在脚本中的应用示例

[plain] view
plain copy

print?





#!/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在读取人工输入中的特殊作用

[plain] view
plain copy

print?





#!/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在脚本中的简单示例

[plain] view
plain copy

print?





#!/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目录存放执行脚本,然后随便执行的简单示例

[plain] view
plain copy

print?





$ 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及以上的单词打印出来

[plain] view
plain copy

print?





#!/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位),来判断上个月天数

[plain] view
plain copy

print?





#!/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】统计文件中每个单词出现的频率

[plain] view
plain copy

print?





#!/bin/sh

# 从标准输入读取文件流,再输出出现频率的前n,默认:25个单词的列表

# 附上出现频率的计数,按照这个计数由大到小排列

# 输出到标准输出

# 语法: wf

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

例子:018】使用while和break等待用户登录


[plain] view
plain copy

print?





#!/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.

例子:019】结合while,case,break,shift做简单的选项处理

[plain] view
plain copy

print?





#!/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

~

【例子:020】read读取多个变量处理,及文本遍历的两种常用方式

[plain] view
plain copy

print?





#!/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

例子:021】复制目录树的两个简单脚本

[plain] view
plain copy

print?





#!/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名磁盘用户,要求清理磁盘空间

[plain] view
plain copy

print?





#!/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

例子:023】将密码文件转换为Shell邮寄列表

[plain] view
plain copy

print?

#!/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

[plain] view
plain copy

print?

#!/bin/bash

cd()

{

command cd "$@" # 实际改变目录

x=$(pwd) # 取得当前目录的名称,传递给变量

PS1="${x##*/}\$ " # 截断前面的组成部分,指定给PS1

}

root$ # 最后输出,类似于这种,看不到目录的完整路径

例子:025】根据XML文件中的license时间来判断是否过期

[plain] view
plain copy

print?

<?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即将在几天后过期。

代码如下:

[plain] view
plain copy

print?

#!/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】根据参数来判断是否要新创建目录

[plain] view
plain copy

print?

#!/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文件拷贝到新目录中

[plain] view
plain copy

print?

#!/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】菜单显示小脚本

[plain] view
plain copy

print?

#!/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

例子:029】判断输入是否为纯字母示例

[plain] view
plain copy

print?

#!/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

~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell 脚本