linux之shell脚本练习

以下脚本已经是在ubuntu下测试的

demo持续更新中。。。

1、for 循环测试,,,Ping 局域网

#!/bin/bash

i=1
for i in {1..254}
do
    # 每隔0.3s Ping 一次,每次超时时间3s,Ping的结果直接废弃
	ping-w 3 -i 0.3 192.168.110.$i > /dev/null
	if [ $? -eq 0  ];then
		echo "192.168.120.$i is rechable"
	else
		echo "192.168.120.$i is unrechable"
	fi
	#let i++
done

2、批量添加用户

#!/bin/bash

user=$(cat /opt/user.txt)

for i in $user
do
	echo "$i"
	useradd "$i"
	echo $i:$i | chpasswd
	#echo "1234" | passwd --stdin $i
done

注意点:

  • ubuntu 不支持--stdin,要用echo 和 chpasswd结合使用
  • 在ubuntu 上要使用$(cat /opt/user.txt),而不是$`cat /opt/user.txt`, 否则通过for 循环遍历时,第一个数据老是给加上$,比如user.txt第一行的数据是user1,它会变成$user1, 

有批量添加,就有批量删除

#!/bin/bash

user=$(cat /opt/user.txt)

for i in $user 
do
	userdel -f $i
done

3、将1-100中的奇数放入数组

#!/bin/bash

for((i=0;i<=100;i++))
do
	if [ $[i%2] -eq 1 ];then
		array[$[$[$i-1]/2]]=$i
	fi
done
#echo ${array[0]}
echo ${array[*]}

运行结果

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99

知识点: 

  • $[] 是用来进行数学运算的,支持+-*%/。效果同$(())
  • $[] 中括号里引用的变量可以不用加$符号,比如上面的 $[i%2]
  • $[i%2]等同于$((i%2))
  • array[*] 表示获取数组中的所有数据

4、创建任意数字及长度的数组,自定义元素

#!/bin/bash

i=0

while true
do
	read -p  "input? yes or no:" operate
	if [ $operate = no ];then
		break
	fi
	read -p "input the value:" value
	array[$i]=$value
	let i++
done

echo ${array[*]}

知识点:

  • [ $doing = no ] 等价于[ $doing = "no" ] , = 是判断字符串的,对于纯字符串所以加不加引号都可

5、将数组中的数小于60的变成60,高于60的不操作

#!/bin/bash

array=(61 62 63 50 59 64)
count=${#array[*]}

echo before:${array[*]}
for((i=0;i<$count;i++))
do
if [ ${array[$i]} -lt 60 ] ; then
	array[$i]=60
fi
done

echo after:${array[*]}

知识点:

  • 数组的定义中的元素之间用空格分开,不要用逗号(,)
  • 数组的长度用 ${#array[*]} 或 ${#array[@]} 获取
  • 数组元素的获取用 ${array[0]} , 赋值的时候不用加$ {}

6、判断数组中最大的数

#!/bin/bash

max=0
array=(1 2 5 3 7 9)
count=${#array[*]}

for((i=0;i<$count;i++))
do
	if [ ${array[$i]} -gt $max ];then
		max=${array[$i]}
	fi
done

echo "the max num of array is ${max}"

知识点:

  •  在取变量的时候需要加$,比如:$max, ${array[0]},再给变量赋值的时候不需要加$比如:max=1, array[0]=1

7、猜数字

#!/bin/bash

seed=(0 1 2 3 4 5 6 7 8 9)
len=${#seed[*]}
random=$[RANDOM%$len]
guess=${seed[$random]}

while :
do
	read -p "0-9?  you guess which one? " doing
	if [ $doing -eq $guess  ]; then
		echo "bingo"
        exit 0
	elif [ $doing -gt $guess  ]; then
		echo "oops, too big"
	else 
		echo "oops, too small"
	fi
	
done

知识点

  • $RANDOM 的范围是 [0, 32767] 
  • :空语句相当于true,即 while : 相当于 while true

8、删除数组中小于60的元素(unset)

#!/bin/bash

num=(58 59 60 61 62)

i=0
for p in ${num[*]}
do
	if [ $p -lt 60 ]; then
		unset num[$i]
	fi
	let i++
done

echo the final result is ${num[*]}
exit 0

知识点:

  • unset 为 shell 内建指令,用于删除定义的可读可写的shell变量(包括环境变量)和shell函数。不能对只读操作。
tt=1
echo $tt
unset tt
echo $tt

9、求1...100的和

#!/bin/bash

sum=0
for i in {1..100} 
do
	sum=$[$sum+$i]
done

echo the result is ${sum}
exit 0

10、求1...50的和(until)

#!/bin/bash

sum=0
i=0

until [ $i -gt 50 ]
do
	#sum=$[$sum+$i]
	let sum+=$i
	let i++
done

echo the result is ${sum}

知识点:

  • let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。

11、石头,剪刀,布

#!/bin/bash

game=(rock paper sissor)
random=$[$RANDOM%3]
scriptResult=${game[$random]}

echo $scriptResult

echo "choose your result:"
echo "1.rock"
echo "2.paper"
echo "3.sissor"

read -p "choose 1, 2 or 3: " choice

case $choice in

	1)
		if [ $[$random+1] -eq 1 ]; then
			echo "equal"
		elif [ $[$random+1] -eq 2 ]; then
			echo "you lose"
		else
			echo "you win"
		fi
		;;
	2)

		if [ $[$random+1] -eq 1 ]; then
			echo "you win"
		elif [ $[$random+1] -eq 2 ]; then
			echo "equal"
		else
			echo "you lose"
		fi
		;;
	3)
		if [ $[$random+1] -eq 1 ]; then
			echo "you lose"
		elif [ $[$random+1] -eq 2 ]; then
			echo "you win"
		else
			echo "equal"
		fi
		;;
	*)
		echo "wrong number"
		;;

esac


exit 0

12、成绩计算(小于60 不及格 85以上优秀)

#!/bin/bash

while :
do
	read -p "input score: " score
	if [ $score -le 100 ] && [ $score -gt 85 ]
	then
		echo "great"
	elif [[ $score -lt 85 &&  $score -ge 60 ]]; then
		echo "normal"
	else
		echo "failed"
	fi
done

exit 0

知识点:

  • [ $score -le 100 ] && [ $score -gt 85 ] 等价于 [[ $score -le 100  &&  $score -gt 85 ]] ,双中括号之间不要有空格,[[ ]] 是shell中的关键字,不是命令,单中括号[],是test命令
  • [[ ]] 不需要注意某些细枝末节,比[]功能强大

  • [[ ]] 支持逻辑运算

  • [[ ]] 支持正则表达式

  • [[]] 关键字

13、计算当前的内存使用百分比

#!/bin/bash

mem_line=$(free -m | grep "Mem")
memory_total=$(echo $mem_line | awk '{print $2}')
memory_used=$(echo $mem_line | awk '{print $3}')

echo "total memory: $memory_total MiB"
echo "used memory: $memory_used MiB"
#echo "usage rate: $[$memory_used/$memory_total * 100]%"
echo "usage rate:" $(echo $mem_line | awk '{printf("%0.2f%", $3 / $2 * 100)}')

exit 0

 知识点:

1、free -m 命令以MiB为单位打印

1 MiB = 1024KiB,   1MB=1000KiB

man free

-m, --mebi Display the amount of memory in mebibytes.
              total        used        free      shared  buff/cache   available
Mem:           3876        1182        1518           3        1175        2428
Swap:           923           0         923

grep "Mem" 会将第二行(Mem开头的那行)抽取出来

2、awk 会进行文本处理, 利用printf函数处理小数

awk '{printf("%0.2f%", $3 / $2 * 100)}'

14、过滤出本机ether网卡的MAC地址

#!/bin/bash

eth=$(ifconfig | grep "ether" | awk '{print $2}')

echo $eth

exit 0

思路也简单,通过ifconfig 获取ether所在行,通过awk获取对应行的第二个参数$2

ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::5e0a:f1cf:cbf8:4c2d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:f6:b6:99  txqueuelen 1000  (Ethernet)
        RX packets 87  bytes 10378 (10.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3992  bytes 720667 (720.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 68614  bytes 4911600 (4.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 68614  bytes 4911600 (4.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

15、统计/var/log有多少个文件,并显示这些文件名

#!/bin/bash

count=0

for file in $(ls /var/log)
do
	echo $file
	if [ -f "/var/log/${file}" ]
	then
		let count++
		echo "file name: $file"
	else
		echo "no file"
	fi
done

echo "the count of files is: ${count}"

echo "the count of files is:" `find /var/log -maxdepth 1 -type f |wc -l`

exit 0

知识点:

  •  如果上述脚本中写成 if [ -f  $file ],就算是文件也会判断失败, file要写成路径的形式,单纯一个名字都会失败,其它文档中写的没有路径,这个注意下

16、打印字母数小于8的单词

for e in `cat ./nowcoder.txt`
do
	if [ ${#e} -lt 8 ];then
		echo ${e}
	fi
done

exit 0

知识点

  • ${#} 用于获取字符串或数组的长度,${#var}:字符串长度, ${#array[*]}:数组长度

17、统计所有进程占用内存百分比的和

统计所有进程占用内存百分比的和_牛客题霸_牛客网 (nowcoder.com)

#!/bin/bash

sum=0
i=0
for m in `awk '{print $4}' ./nowcoder.txt`
do
    if [ $i -eq 0 ];then
        let i++
        continue
    fi
    r=$(echo $m | bc)
    sum=$(echo $r + $sum | bc)
done
echo $sum | bc

exit 0
   

知识点:

  • 利用bc处理小数,这里是利用的+,,$(echo $r + $sum | bc)

18、统计每个单词出现的个数

打印无顺序(利用字典)

#!/bin/bash

declare -A dic

for word in `cat nowcoder.txt`
do
    if [ $word = "" ];then
        continue
    fi
    if [ -v dic[$word] ]; then
        r=${dic[$word]}
        dic[$word]=`expr $r + 1`
    else
        dic[$word]=1
    fi
done

for key in `echo ${!dic[*]}`
do
    echo "$key ${dic[$key]}"
done

exit 0


利用文件处理顺序

#!/bin/bash

declare -A dic

for word in `cat nowcoder.txt`
do
	if [ $word = "" ];then
		continue
	fi
	if [ -v dic[$word] ]; then
		r=${dic[$word]}
		dic[$word]=`expr $r + 1`
	else
		dic[$word]=1
	fi
done

rm tmp.txt
touch tmp.txt

for key in `echo ${!dic[*]}`
do
	echo "${dic[$key]} $key" >> tmp.txt
done

cat tmp.txt | sort -n |awk  '{print $2,$1}'
exit 0

知识点:

1、字典声明用declare -A dic

2、字典赋值dic[key]=value

3、获取所有key , ${!dic[*]}

4、获取所有value, ${dic[*]}

linux 程序设计 第四版 shell 脚本

已调试,大致没问题,想学习的复制拿去

#!/bin/sh

menu_choice=""
current_cd=""
title_file="title.cdb"
tracks_file="tracks.cdb"
temp_file=/tmp/cdb.$$
trap 'rm -f $temp_file' EXIT

get_return() {
	echo "Please return \c"
	read x
	return 0
}

get_confirm() {
	echo -e "Are you sure? \c"
	while true
	do
		read x
		case "$x" in
			y | yes|Y|Yes|YES) return 0;;
			n | no|N|No|NO) 
				echo
				echo "Cancelled"
				return 1;;
			*) echo "Please enter yes or no";;
		esac
	done

}

set_menu_choice() {
	clear
	echo "Options : -"
	echo
	echo "   a) Add new CD"
	echo "   f) Find CD"
	echo "   c) Cont the CDs and tracks in the catalog"
	if [ "$cdcatnum" != "" ]; then
		echo "   l) List track on $cdtitle"
		echo "   r) Remove $cdtitle"
		echo "   u) Update track information for $cdtitle"
	fi
	echo "   q) Quit"
	echo 
	echo  "Please enter choice then press return \c"
	read menu_choice
	return
}

insert_title() {
	echo $* >> $title_file
	return
}

insert_track() {
	echo $* >> $tracks_file
	return
}

add_record_tracks() {
	echo "Enter track information for this CD"
	echo "When no more tracks enter q"
	cdtrack=1
	cdtitle=""
	while [ "$cdtitle" != "q" ] 
	do
		echo "Track $cdtrack, track title? \c"
		read tmp
		cdtitle=${tmp%%, *}
		echo ${tmp}======
		echo ${cdtitle}-------
		if [ "$tmp" != "$cdtitle" ]; then
			echo "Sorry, no commas allowed"
			continue
		fi

		if [ -n "$cdtitle" ]; then
			echo enter
			echo ${cdtitle}-------
			if [ "${cdtitle}" != "q" ]; then
				echo enter1
				insert_track $cdcatnum, $cdtrack, $cdtitle
			fi
		else
			cdtrack=$((cdtrack-1))
		fi
	  cdtrack=$((cdtrack+1))
	done
}

add_records() {
	echo "Enter catalog name \c"
	read tmp;
	cdcatnum=${tmp%%, *}
	echo "Enter title \c"
	read tmp
	cdtitle=${tmp%%, *}
	
	echo "Enter type \c"
	read tmp
	cdtype=${tmp%%, *}
	
	echo "Enter artist/composer \c"
	read tmp
	cdac=${tmp%%, *}

	echo About to add new entry
	echo "$cdcatnum $cdtitle $cdtype $cdac"
	
	if get_confirm; then
		insert_title $cdcatnum, $cdtitle, $cdtype, $cdac
		add_record_tracks
	else
		remove_records
	fi
	return
}

find_cd() {
	if [ "$1" = "n" ] ; then 
		asklist=n
	else
		asklist=y
	fi
	cdcatnu=""
	echo -e "Enter a string to search for in the CD titles \c"
	read searchstr

	if [ "$searchstr" = "" ] ; then
		return 0
	fi
	
	grep "$searchstr" $title_file > $temp_file
	
	set $(wc -l $temp_file)
	linesfound=$1
	
	case "$linesfound" in

	0)   echo "Sorry, nothing found"
		get_return
		return 0;;
	1)  ;;
	2)  echo "Sorry, not unique"
		echo "Found the following"
		cat $temp_file
		get_return
		return 0
	esac

	IFS=","
	read cdcatnum cdtitle cdtype cdac < $temp_file
	IFS=" "

	if [ -z "$cdcatnum" ]; then
		echo "Sorry, cound not extract catalog field from $temp_file"
		get_return
		return 0
	fi
	
	echo

	echo Catalog num: $cdcatnum
	echo Title: $cdtitle
	echo TYPe: $cdtype
	echo Artist: $cdac
	echo
	get_return
	if [ "$asklist" = "y" ]; then
		echo -e "View tracks for this CD? \c"
		if [ "$x" = "y" ]; then
			echo
			list_tracks
			echo
		fi	
	fi
	return 1
}


update_cd() {

	if [ -z "$cdcatnum" ]; then
		echo "You must select a CD first"
		find_cd n
	fi

	if [ -n "$cdcatnum" ]; then 
		echo "Current tracks are: -"
		list_tracks
		echo
		echo "This will re_enter the tracks for $cdtitle"
		get_confirm && {
			grep -v "^${cdcatnum}," $tracks_file > $temp_file
			mv $temp_file $tracks_file
			echo
			add_record_tracks
		}
	fi
	return
}

count_cds() {
	set $(wc -l $title_file)
	num_titles=$1
	set $(wc -l $tracks_file)
	num_tracks=$1
	echo found $num_title CDs, with a total of $num_tracks tracks
	get_return
	return
}

remove_records() {
	if [ -z "$cdcatnum" ]; then
		echo You must select a CD first
		find_cd n
	fi

	if [ -n "$cdcatnum" ]; then
		echo "You are about to delete $cdtitle"
		get_confirm && {
			grep -v "^${cdcatnum}," $title_file > $temp_file
			mv $temp_file $title_file
			grep -v "^${cdcatnum}," $tracks_file > $temp_file
			mv $temp_file $tracks_file
			cdcatnum=""
			echo Entry removed
		}
		get_return
	fi

	return
}


list_tracks() {
	if [ "$cdcatnum" = "" ]; then
		echo no CD selected yet
		return
	else
		grep "^${cdcatnum}," $tracks_file > $temp_file
		num_tracks=$(wc -l $temp_file)
		if [ "$num_tracks" = "0" ]; then
			echo no tracks found for $cdtitle
		else {
			echo
			echo "$cdtitle :-"
			echo 
			cut -f 2- -d, $temp_file
		} | ${PAGER:-more}
		fi
	fi
	get_return
	return
}

rm -f $temp_file

if [ ! -f $title_file ];then
	touch $title_file
fi

if [ ! -f $title_file ]; then
	touch $tracks_file
fi

clear
echo
echo
echo "Mini CD manager"
sleep 1

quit=n
while [ "$quit" != "y" ];
do
	set_menu_choice
	case "$menu_choice" in
		a)  add_records;;
		r)  remove_records;;
		f)  find_cd y;;
		u)  update_cd;;
		c)  count_cds;;
		l)  list_tracks;;
		b)  
			echo
			more $title_file
			echo
			get_return
			;;	
		q|Q) quit=y;;
		*) echo "Sorry, choice not recognized";;
	esac
done

rm -f $temp_file
echo "Finished"
exit 0

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俯仰一世_1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值