学习shell笔记上

文章目录

    • SHELL脚本编程
      • 一、变量类型
        • 环境变量
        • 局部变量
        • 位置变量
          • \$@ 与 \$#的不同
        • 普通变量
    • 二、变量的基本使用
        • 1、命名规则
          • 硬性标准
          • 隐性标准
        • 2、赋值方式
        • 3、变量的引用方式
        • 5、删除变量
        • 6、状态码显示
    • 三、命令执行顺序
    • 四、shell 的运行环境
        • 1、$- 变量,定制 shell 环境
        • 2、set -u 和 -e 选项
        • 3、printf 选项
        • 4、shell 环境配置文件
    • 五、逻辑运算
        • 1、算数符
        • 2、计算方式
        • 3、随机数生成器
        • 4、逻辑运算
        • 5、条件测试运算
          • 变量测试
          • 数值测试
          • [[ ]] 的用法
        • 6、() 与 { } 执行命令的不同
        • 7、组合测试条件
    • 六、编写脚本
        • 1、编写脚本命令
          • read 命令
          • 测试主机是否可以正常通信脚本
        • 2、循环判断小脚本

SHELL脚本编程

一、变量类型

环境变量

生效范围为当前shell,该shell之后生成的子shell都会带有该变量内容,但是该shell子shell定义的全局变量不会继承给上级shell

[root@localhost ~]# export a=c
[root@localhost ~]# echo $a
c
[root@localhost ~]# bash
[root@localhost ~]# echo $a
c
[root@localhost ~]# export b=v
[root@localhost ~]# echo $b
v
[root@localhost ~]# exit
exit
[root@localhost ~]# echo $b

局部变量

只在当前shell中生效,不会对子shell生效

[root@localhost ~]# a=c
[root@localhost ~]# bash
[root@localhost ~]# echo $a

位置变量

根据参数的位置,定义变量名称,$1$2$3…

$1	# 第一个参数
$2	# 第二个参数
$10 # 10之后的变量都需要使用 {} 来对变量名称扩起,为了生命主体
$@	# 输出所有参数
$#	# 输出位置参数个数
$*	# 与 $@ 差不多相同

[root@localhost ~]# cat sh.sh 
#!/bin/bash
echo $1
echo $2
echo ${10}
echo $@
echo $#
echo $*

[root@localhost ~]# bash sh.sh a b c d e f j l z m c 
a
b
m
a b c d e f j l z m c
11
a b c d e f j l z m c

$@ 与 $#的不同
# 当我们在 shell 脚本中定义了循环主体为 $@ 后那么输出的结果就是单个的字符进程处理
# 当我们在 shell 脚本中定义了循环主题为 $* 后那么输出结果就是所有字符串一起输出,作为一个整体
[root@localhost ~]# cat sh.sh 
#!/bin/bash
for i in "$@"
do
	echo $i
done
for j in "$*"
do
	echo $j
done

[root@localhost ~]# bash sh.sh a b c d e f g
a
b
c
d
e
f
g
a b c d e f g

普通变量

普通变量就是普通赋值

二、变量的基本使用

1、命名规则

硬性标准
  • 不能使用 shell 的保留字及内置变量进行赋值,例如 for if 等

  • 变量名必须以数字或字母以及下划线,变量名中不可以有 - 来作为变量名

隐性标准
  • 使用大驼峰模式 NameIs 或者小驼峰 nameIs 来命名变量
  • 在命名变量时不要使用简写,要使变量名在其他人使用时同样可以一眼知意
  • 局部变量小写,环境变量大写

2、赋值方式

# 使用字符串直接赋值
[root@localhost ~]# Name="My name is jason_chen"
[root@localhost ~]# echo $Name
My name is jason_chen

# 变量之间赋值
[root@localhost ~]# name="chen"
[root@localhost ~]# Name=$name
[root@localhost ~]# echo $Name
chen

# 使用 `` 反撇号赋值命令执行结果
[root@localhost ~]# ls_data=`ls`
[root@localhost ~]# echo $ls_data
anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public sh.sh Templates Videos

# 变量追加值
[root@localhost ~]# Name=chen
[root@localhost ~]# age=19
[root@localhost ~]# Name+=$age
[root@localhost ~]# echo $Name
chen19

[root@localhost ~]# Name=chen
[root@localhost ~]# Name+=:$age
[root@localhost ~]# echo $Name
chen:19

3、变量的引用方式

# 使用 ${} 进行调用变量,相当于声明变量主体来进行调用
[root@localhost ~]# echo ${Name}
chen

# 使用 "" 调用变量,变量在 "" 会输出变量内存储的内容
[root@localhost ~]# echo "$Name"
chen

# 使用 '' 调用变量,变量在 '' 不会输出存储内容,只会将变量名相当于一个字符串进行输出
[root@localhost ~]# echo '$Name'
$Name

# 如果想要输出两个变量的组合,但是如果中间有特殊字符将两个变量隔开后,那么系统在识别变量的时候将会识别到 $Name_ 而不是 $Name 所以输出结果就只有 $age 的内容
[root@localhost ~]# echo $Name_$age
19
# 使用 ${} 将变量扩起,这样就不会造成系统识别变量错误的情况了
[root@localhost ~]# echo ${Name}_$age
chen_19

# 直接调用与加上双引号调用的区别,根据变量名直接调用 echo 只是将结果整体输出,作为一个整体的字符串,而如果加上双引号的话输出结果会根据位置来单个输出
[root@localhost ~]# echo $ls_data
anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public sh.sh Templates Videos
[root@localhost ~]# echo "$ls_data"
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
Music
Pictures
Public
sh.sh
Templates
Videos

5、删除变量

  • 变量删除的重要性:当我们在脚本中定义多个变量时,在脚本结束或者变量使用完成后一定要养成释放变量的习惯,因为如果脚本过于庞大或者脚本定义变量过多时,容易造成内存溢出的情况,会造成服务器崩溃。shell 脚本是在脚本执行完成后释放所有变量。
[root@localhost ~]# Name=chen
[root@localhost ~]# echo $Name
chen
[root@localhost ~]# unset Name
[root@localhost ~]# echo $Name

6、状态码显示

类似于浏览器返回的 403、404 脚本中也可以自己定义返回值,来根据返回值判断脚本执行状况

# $? 的执行,成功后返回结果为 0,失败后返回结果为 1-255
[root@localhost ~]# ls /date/
error.log  seccess.log
[root@localhost ~]# echo $?
0
# 此时我的 / 目录下并没有 /aaa 目录,所以在查看一个不存在的目录时当然会报错
[root@localhost ~]# ls /aaa
ls: cannot access /aaa: No such file or directory
[root@localhost ~]# echo $?
2

# $? 的使用,通过 if 直接来判断 $? 的值,来返回结果
[root@localhost ~]# ls /aaa; if [ $? -eq 0 ];then echo "yes"; else echo "no"; fi
ls: cannot access /aaa: No such file or directory
no
[root@localhost ~]# ls /date; if [ $? -eq 0 ];then echo "yes"; else echo "no"; fi
error.log  seccess.log
yes

自定义返回值

# 如果自定义返回值后,不论你的命令执行成功与否都会返回自己定义的返回值,在脚本中使用该 exit 命令来判断脚本执行状态是很有用的哇!
[root@localhost ~]# (ls /data/;exit 100)
ls: cannot access /data/: No such file or directory
[root@localhost ~]# echo $?
100
[root@localhost ~]# (ls /date;exit 100)
error.log  seccess.log
[root@localhost ~]# echo $?
100

三、命令执行顺序

# 可以使用转义符 \ 来取消特殊符号的特殊含义
# '' 双引号防止所有扩展
# "" 防止扩展,但是如果加上 $ 符号后就不会防止扩展
1. 将命令行分成单个命令词
2. 展开别名
3. 展开大括号的声明 {}
4. 展开波浪符生命 ~
5. 命令替换 $() 和 ``
6. 再次命令分解成命令词
7. 展开文件通配符 *\?\[abc] 等
8. 准备 I/O 重定向
9. 运行命令

四、shell 的运行环境

1、$- 变量,定制 shell 环境

[root@localhost ~]# echo $-
himBH

i:表示该 shell 是一个交互式的终端,默认情况在脚本执行时 i 是关闭的
m:打开监控模式,可以通过 job 来控制进程的后台


# h:打开选项后,shell 会将命令所在的路径 hash 记录下来,避免下次执行命令时还会查询。
[root@localhost ~]# hash
hits	command
   1	/bin/ls
   1	/bin/find
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# set +h 
[root@localhost ~]# hash
-bash: hash: hashing disabled

# B:大括号扩展
[root@localhost ~]# echo {1..100}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

# H:history 命令,!n 即可执行 history 中的历史命令
[root@localhost ~]# set +B
[root@localhost ~]# echo {1..100}
{1..100}

  909  ls
  910  history
[root@localhost ~]# !909
-bash: !909: command not found
[root@localhost ~]# set -H
[root@localhost ~]# !909
ls
anaconda-ks.cfg  Documents  install.log         Music     Public  Templates
Desktop          Downloads  install.log.syslog  Pictures  sh.sh   Videos

2、set -u 和 -e 选项

# set -u 选项,如果脚本中的变量没有定义,那么会直接结束脚本,不会继续执行
[root@localhost ~]# cat sh.sh 
#!/bin/bash
echo $a
[root@localhost ~]# sh sh.sh 

[root@localhost ~]# cat sh.sh 
#!/bin/bash
set -u
echo $a
set +u
[root@localhost ~]# sh sh.sh 
sh.sh: line 3: a: unbound variable

# set -e 选项,如果脚本中任何一个位置返回一个非零的返回值就会结束脚本

3、printf 选项

[root@localhost ~]# printf "(%s)\n" 1 2 3 4
(1)
(2)
(3)
(4)
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# printf "(%s)" 1 2 3 4
(1)(2)(3)(4)

4、shell 环境配置文件

# 将命令放在每个文件最前
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc

# 将命令放在每个文件最后
/etc/profile.d/*.sh
/etc/bashrc
/etc/profile
/etc/bashrc
~/.bashrc
~/.bash_profile
profile 类
为交互式登陆的 shell 提供配置
全局:/etc/profile /etc/profile.d/*.sh
个人:~/.bash_profile
bashrc 类
为非交互式登录和交互式登陆的 shell 提供配置
全局:/etc/bashrc
个人:~/.bashrc
source [filename]		# 可以让文件配置立即生效

五、逻辑运算

1、算数符

* / % 	# 乘,除,(取余取模)
+ - 	# 加、减
i++ i--	# 自增、自减
++i --i	# 自增、自减
	i++与++i的区别
	[root@localhost ~]# i=1;let var=i++;echo $var
1
	[root@localhost ~]# i=1;let var=++i;echo $var
2
= *= /= %= += -= <<= >>= &= ^= |=
	<<= >>= # 是二进制移位
! ~	# 取反
**	# 乘方
<< >> # 移位
<= >= < > 	# 大于小于
== !=	# 等于,不等于
&		# and 符号
|		# or 符号
^		# 异或符号
&&		# 逻辑 and 符号
||		# 逻辑 or 符号

2、计算方式

# let 计算方式
[root@localhost ~]# let var=1+1
[root@localhost ~]# echo $var
2

# (())	计算方式
[root@localhost ~]# ((var=1*3))
[root@localhost ~]# echo $var
3

# $[] 计算方式
[root@localhost ~]# var=$[1*4]
[root@localhost ~]# echo $var
4

3、随机数生成器

$RANDOM
# 生成一个 0-50 的随机数
[root@localhost ~]# echo $((RANDOM%50))
26
[root@localhost ~]# echo $[RANDOM%50]
45

4、逻辑运算

根据布尔值决定后面的命令执行

& 	and 符号,前一个命令执行后,后一个才可以继续执行
| 	or 符号,前一个执行后一个就不会执行
^ 	异或符号,根据二进制取出异或值

5、条件测试运算

test [expression]
[ expression ]	# 与 test 相同
[[ expression ]]	# []的升级版

-a		# 测试文件是否存在
-b		# 测试文件是否为块设备文件
-c		# 测试文件是否为字符设备文件
-d		# 测试文件是否为目录
-e		# 测试文件是否存在
-f		# 测试文件是否为普通文件
-h		# 测试文件是否为链接文件
-L		# 与 -h 相同
-r		# 测试我呢见是否刻度
-s		# 测试文件是否为空
-w		# 测试文件是否可写
-x		# 测试文件是否可执行
-z		# 测试文件是否为空
-n		# 测试文件是否不为空
-v		# 测试变量是否定义
变量测试
# -v 测试变量是否定义
[root@DNS ~]# test -v $b
[root@DNS ~]# echo $?
0
[root@DNS ~]# b=10
[root@DNS ~]# test -v $b
[root@DNS ~]# echo $?
1

[root@DNS ~]# [[ -v $b ]]
[root@DNS ~]# echo $?
1

[root@DNS ~]# [ -v $b ]
[root@DNS ~]# echo $?
1
数值测试
-eq 是否等于
-lt 是否小于
-le 是否小于等于
-gt 是否大于
-ge 是否大于等于
-ne 是否不等于
# 定义变量并使用数值判断,来判断变量内容是否大于等于或者相等
[root@DNS ~]# i=10
[root@DNS ~]# j=20

[root@DNS ~]# [ $i -eq $j ]
[root@DNS ~]# echo $?
1
[root@DNS ~]# [ $i -lt $j ]
[root@DNS ~]# echo $?
0
[root@DNS ~]# [ $i -gt $j ]
[root@DNS ~]# echo $?
1
[root@DNS ~]# [[ $i -gt $j ]]
[root@DNS ~]# echo $?
1

算数表达比较

==		等于
!=		不等于
<=		小于等于
>=		大于等于
>		大于
<		小于
[root@DNS ~]# x=10;y=10;[ $x == $y ];echo $?
0
[root@DNS ~]# x=10;y=10;((x == y ));echo $?
0

字符串表达比较

# -z	测试字符串是否为空,没定义或者为空为真,只要定义不空就是假
[root@DNS ~]# [ -z $x ]
[root@DNS ~]# echo $?
0
[root@DNS ~]# x=10
[root@DNS ~]# [ -z $x ]
[root@DNS ~]# echo $?
1

# -n	测试字符串是否不空,没定义或者为空为假,只要定义不空就是真
# 变量必须要加双引号,因为如果不加双引号 -n 就是判断的字符串大于 0,即为真,如果加上双引号,那么 -n 选项判断的就是该变量内的数据,而不是变量名本身。
[root@localhost ~]# [ -n "$x" ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# x=asd
[root@localhost ~]# [ -n "$x" ]
[root@localhost ~]# echo $?
0
[[ ]] 的用法
[[ expression ]] 用法
==	左侧字符串是否与右侧的 PATTERN 相同
=~	左侧字符串是否能被右侧的表达式匹配

通配符*

[root@localhost ~]# File=ab;[[ $File == a* ]]
[root@localhost ~]# echo $?
0

[root@localhost ~]# File=a*;[[ $File == a\* ]]
[root@localhost ~]# echo $?
0

[root@localhost ~]# File=a*;[[ $File == a"*" ]]
[root@localhost ~]# echo $?
0

通配符 ?

[root@localhost ~]# File=123;[[ $File == ?? ]];echo $?
1
[root@localhost ~]# File=123;[[ $File == ??? ]];echo $?
0

例子:判断合理的成绩

[root@localhost ~]# score=100;[[ $score =~ ^(100|[0-9][0-9])$ ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# score=101;[[ $score =~ ^(100|[0-9][0-9])$ ]]
[root@localhost ~]# echo $?
1

例子:使用 [[ ]] 判断文件后缀

[root@localhost ~]# file=a.txt;[[ $file == *.txt ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# file=a.txt;[[ $file =~ \.txt$ ]]
[root@localhost ~]# echo $?
0

例子:判断非负整数

[root@localhost ~]# num=123a;[[ $num =~ ^[0-9]+$ ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# num=a123;[[ $num =~ ^[0-9]+$ ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# num=1a23;[[ $num =~ ^[0-9]+$ ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# num=123;[[ $num =~ ^[0-9]+$ ]]
[root@localhost ~]# echo $?
0

例子:判断合法 IP

[root@localhost ~]# ipadd=224.0.0.1 ;[[ $ipadd  =~  ^(([1-9]?[0-9]|1[0-9]{2}|2[0-5]{2})\.){3}([0-9]|1[0-9]{2}|2[0-5]{2})$ ]]&&echo $ipadd
224.0.0.1

6、() 与 { } 执行命令的不同

()	会创建一个子进程来执行括号中的命令,更加安全,会继承父进程非环境变量的变量。
{}	在当前进程执行,会修改当前的 shell 环境。
[root@localhost ~]# name=chen;(echo $name;name=ding;echo $name);echo $name
chen
ding
chen

[root@localhost ~]# name=chen;{ echo $name;name=ding;echo $name; };echo $name
chen
ding
ding

7、组合测试条件

# 只支持 [] 不支持 [[ ]]
-a		并且,按位与
-o		或者,按位或
[root@localhost ~]# a=10;b=10; [ $a == $b -a $b == $a ] && echo "chen"
chen

[root@localhost ~]# a=10;b=10; [ $a == $b -o $x == $a ] && echo "chen"
chen

六、编写脚本

1、编写脚本命令

read 命令
read 控制用户输入内容
	-p 显示提示信息
	-s 静默输入
	-n 定义输入字符疮毒
	-d '结束符' 定义结束符
	-t 定义结束时间
[root@localhost ~]# echo "1 2" >>1.txt ;read a b <1.txt;echo $a+$b|bc
3
[root@localhost ~]# echo 1 2|(read z v;echo $z $v);echo $z $v
1 2
[root@localhost ~]# echo 1 2|{ read z v;echo $z $v;};echo $z $v
1 2
[root@localhost ~]# echo 1 2|read z v;echo $z $v
测试主机是否可以正常通信脚本
#!/bin/bash
read -p "Please ping hostipaddress ---> " ipaddr

[[ $ipaddr  =~  ^(([1-9]?[0-9]|1[0-9]{2}|2[0-5]{2})\.){3}([0-9]|1[0-9]{2}|2[0-5]{2})$ ]] && ping -w 1 $ipaddr && echo "该主机通信正常!" || echo "该主机通信有故障!"


升级版
[root@localhost test]# cat hostip.list 
172.16.1.254
172.16.1.9
123.123.3.4
www.baidu.com
asd.awd.asdzx.

#!/bin/bash
DIR=/date
success="seccess.log"
error="error.log"
function access() {
    cmd='echo `date +%F` $i >>$DIR/$1'
    [[ -e $DIR ]] && eval $cmd || (mkdir $DIR && eval $cmd)
}
for i in `cat /test/hostip.list`
do
	ping -w 1 $i
	if [ $? -eq 0 ];then
		access $success
	else
		access $error
	fi
done

2、循环判断小脚本

范例:写出身体质量指数测试脚本

#!/bin/bash
clear
echo "欢迎使用傻妞侧重仪器!"
cat <<EOF
---------
   *
  * *
*******
  *  *
*    *
---------
EOF
read -p "请输入你的身高(m):" height
read -p "请输入你的体重(kg):" weight

BMI=`echo ${weight}/${height}^2 | bc`
if [[ $BMI -ge 18 && $BMI -le 25 ]]
then
   echo "太瘦了,多吃点吧,不然要死掉了"
elif [[ $BMI -ge 26 && $BMI -le 30 ]]
then
   echo "哇塞,这就是玉树临风的你吗,终于见到你了,你一点都不胖呢,你是最帅的!"
elif [[ $BMI -ge 31 && $BMI -le 35 ]]
then
   echo "你TM为什么这么胖呢!!"
elif [[ $BMI -ge 36 && $BMI -le 40 ]]
then
   echo "疾病将伴你而来"
else
   echo "神仙下凡,抱歉,我测不出来"
fi

范例:史上最牛逼用户管理软件

#!/bin/bash
function view() {
clear
echo "恭喜你开启了新大门,你的成人之路从现在开始!come on baby!"
cat <<EOF
   ---1 useradd
   ---2 vive user
   ---3 deluser
   ---4 quit
EOF
read -p "Please is num" num
}

function image() {
cat <<EOF
         ┏┓  ┏┓
    ┏┛┻━━━┻┗┓
    ┃    ┃
    ┃   ━   ┃
    ┃ ┳┛ ┗┳ ┃
    ┃       ┃
    ┃   ┻   ┃
    ┗━┓ 新 ┏━┛
      ┃ 东 ┃
  ┏━━━┛ 方 ┃
 ┏┫     神 ┃
 ┗┓ *** 兽 ┃
  ┗┓┏┳━┓┏┏┛
   ┣┣┃ ┣┣┃
   ┗┻┛ ┗┻┛
EOF
}
function judgment() {
   read -p "y/y/y/y/y/y/y/y not found no:" useridea
   [[ $useridea =~ ^([yY])$ ]] && (echo "再给你一次机会,重新来,就知道你舍不得我!"; break) 
}

read -p "Please username " username
while true
do
id $username &> /dev/null
if [ $? -eq 0 ]
then
   clear
   echo "该用户已经存在啦,你还想干嘛,不要对我有非分之想!"
   read -p "go out  (Y/N)" nnn
   [[ $nnn =~ ^([Nn]|[Nn][oO])$ ]] && view || ([[ $nnn =~ ^([Yy]|[Yy][Ee][Ss])$ ]] && echo "呸,给你机会你不重用啊!")
   case $num in
      1)
         clear
         image
         useradd $username
         read -p "请输入你进入成人之路的钥匙,美眉在等着你:" passwd
         echo $username:$passwd | chpasswd $username
         [[ $? -eq 0 ]] && echo "创建成功" || echo "失败了呀,行不行啊,就这???"
         echo -n "再给你一次机会,不要墨迹!"
         judgment
         ;;
      2)
         clear
         image
         read -p "请问你要使用哪种方式 insert /大写“I” 小写“i” : " viewuser
         [[ $viewuser =~ ^([I]|[i])$ ]] && id $username || echo "重新执行吧,不给你机会了 go out"
         exit
         ;;
      3)
         clear
         image
         echo -n "你真的要把我删掉了吗?"
         judgment
         ;;
      4)
         clear
         image
         read -p "跟我说声谢谢,快点!" Thks
         [[ $Thks == "谢谢" ]] && echo "滚吧!渣男!";exit 999;
         ;;
   esac
else
   echo "没有就没有吧,你再看看其他地方,爱有没有,滚犊子"
fi
done

面试题:1-100 的和

[root@DNS test]# seq 100|paste -s|tr -s '\t' '+'|bc
[root@DNS test]# seq 100|paste -sd +|bc
[root@DNS test]# sum=0;for i in {1..100};do let sum+=$i; done;echo $sum
5050

面试题:1-100 中的偶数和

[root@DNS test]# echo {2..100..2} | tr ' ' '+'|bc
2550
[root@DNS test]# seq 2 2 100|paste -sd +|bc
2550
[root@DNS test]# sum=0;for i in {1..100};do ((i%2 == 0)) && let sum+=$i; done;echo $sum
2550

面试题:1-100 中的奇数和

[root@DNS test]# echo {1..100..2}|tr ' ' '+'|bc
2500
[root@DNS test]# seq 1 2 100|paste -sd +|bc
2500
[root@DNS test]# sum=0;for i in {1..100};do ((i%2 == 0 )) || let sum+=$i; done; echo $sum
2500

面试题:创建 1…10user 十个用户,并设置随机密码

#!/bin/bash
for i in {1..10}
do
  passwd=`cat /dev/urandom|tr -dc "[:alnum:]"|head -c12`
  useradd user$i
  echo user${i}:${passwd} |tee -a 1.txt |chpasswd user${i}
done

面试题:批量修改文件后缀名

#!/bin/bash
DIR=/test/demo/
cd $DIR
for i in *
do
   filename=`echo $i | grep -Eo '.*\.'`;
   mv $i ${filename}bak
done

面试题:要将YY-MM-DD下的所有文件移动到YY-MM/DD目录中

mkdir file.sh
#!/bin/bash
for i in {1..365}
do
  DIRNAME=`date -d "-$i day" +%F`
  [ -d /test/test ] && mkdir -p /test/test/$DIRNAME || mkdir -p /test/test/
  cd /test/test/$DIRNAME
  touch ${RANDOM}.log
done

cat mvfile.sh
#!/bin/bash
for i in *
do
  DIR=`echo $i | cut -d '-' -f1,2`
  DD=`echo $i | cut -d '-' -f3`
  [ -d /data/demo/$DIR/$DD ] || mkdir -p /data/demo/$DIR/$DD/
  mv ${i}/* /data/demo/$DIR/$DD/
done

例题:判断 /var 下面所有文件类型

#!/bin/bash
for filename in `du -a /var/|grep -Eo "/.*[a-z]$"`
do
   [[ -d $filename ]] && echo "$filename is directory" >>/data/directory.list
   [[ -f $filename ]] && echo "$filename is file" >> /data/file.list
   [[ -b $filename ]] && echo "$filename is block_file" >> /data/block.list
   [[ -L $filename ]] && echo "$filename is link_file" >> /data/link_file.list
done

例题:更改 /etc/rc.d/rc3.d 目录下有多个文件,将 K 开头的加上 stop 以 S 开头的加上 start

#!/bin/bash
for i in *
do
	[[ `echo $i|head -c 1` -eq 'S' ]] && `mv $i $i'start'`
	[[ `echo $i|head -c 1` -eq 'K' ]] && `mv $i $i'start'`
done

例题:每隔 3 秒钟到系统上获取已经登陆的用户的信息,如果发现用户 chending 登录,那么就记录登陆的时间并记录到日志 /var/log/login.log 中

#!/bin/bash
while true
do
   [[ $(who | grep chen) && $(eval "date '+%F %H:%M:%S':chending已经登录" >>/var/log/login.log;) ]]
   sleep 3
done

例题:随机生成 10 以内的数字,实现猜字游戏,提示比较大小,相等就退出

#!/bin/bash
while true
do
  random=$[RANDOM%10]
  read -p "请输入你的幸运数字:" num
  [[ random -eq  num ]]  && ( echo "你是真 TM 牛逼,猜中了" ) && exit || ( echo "重来吧姐们/哥们!" )
done

你可能感兴趣的:(shell)