变量名:
变量名可以自定义。如果不指定变量名,则会把输入保存到默认变量REPLY中;
如果只提供了一个变量名,则将整个输入行赋予该变量;
如果提供了一个以上的变量名,则输入行分为若干字,一个接一个地赋予各个变量,而命令行
上的最后一个变量取得剩余的所有字
变量
Shell Script是一种弱类型语言,使用变量的时候无需首先声明其类型。
新的变量会在本地数据区分配内存进行存储,这个变量归当前的Shell所有,
任何子进程都不能访问本地变量。这些变量与环境变量不同,环境变量被存储在另一内存区,叫做用户环境区,这块内存中的变量可以被子进程访问。
变量赋值的方式是:
variable_name=variable_value
注意:等号两边不要有空格,否则会报错的。
如果对一个已经有值的变量赋值,新值将取代旧值。取值的时候要在变量名前加,variable_name
可以在引号中使用,
这一点和其他高级语言是明显不同的。如果出现混淆的情况,可以使用花括号
来区分。
例如:
#!/bin/sh
#Athor: TZ edu
str="hello world"
echo $str
echo "shell say $str"
echo "shell say $strs"
echo "shell say ${str}s"
结果
前面讲过,位置参数变量是可以把用户的输入用参数的方式输入脚本的,
不过这种输入方式只有写这个脚本的人才能确定需要输入几个参数,
每个参数应该输入什么类型的数据,并不适合普通用户使用。
除位置参数变量外,我们也可以使用 read 命令向脚本中传入数据。
read 命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。
得到输入后,read 命令将数据放入一个标准变量中。
read 命令格式如下:
[root@localhost ~]# read [选项] [变量名]
选项:
-p "提示信息":在等待read输入时,输出提示信息;
-t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间;
-n 字符数:read命令只接收指定的字符数就会执行;
-s: 隐藏输入的数据,适用于机密信息的输入;
示例
#!/bin/bash
read -t 30 -p "Please input your name:" name
#提示"请输入姓名"并等待30秒,把用户的输入保存到变量name中
echo "Name is $name"
#看看变量"$name"中是否保存了你的输入
read -s -t 30 -p "Please enter your age:" age
#提示"请输入年龄"并等待30秒,把用户的输入保存到变量age中
#年龄是隐私,所以我们用"-s"选项隐藏输入
echo -e "n"
#调整输出格式,如果不输出换行,则一会儿的年龄输出不会换行
echo "Age is $age"
read -n 1 -t 30 -p "Please select your gender[M/F]:" gender
#提示"请选择性别"并等待30秒,把用户的输入保存到变量gender中
#使用"-n 1"选项只接收一个输入字符就会执行(无须按回车键)
echo -e "\n"
echo "Sex is $gender"
结果
在这里插入代码片
控制流程
条件
if语句
if语句格式
if ...; then
...
elif ...; then 等价 if(){}else if(){}
...
else
...
fi
Shell Script中if语句的条件部分要以分号来分隔
,若是条件测试的话,需要将条件用[]包起来,且括号两边必须要有空格。
常见的条件测试如下:
- 整数比较:
-eq 测试两个整数是否相等
-ne 测试两个整数是否不等
-gt 测试一个数是否大于另一个数
-lt 测试一个数是否小于另一个数
-ge 大于或等于
-le 小于或等于
- 字符串比较:
== 等于 两边要有空格
!= 不等
> 大于
< 小于
-z string 当串的长度为0时为真
-n string 当串的长度大于0时为真
- 文件比较:
-e file 测试文件是否存在
-f file 测试文件是否为普通文件
-d file 测试指定路径是否为目录
-r file 测试文件对当前用户是否可读
-w file 测试文件对当前用户是否可写
-x file 测试文件对当前用户是都可执行
- 组合测试条件:
-a: and
-o: or
!: 非
示例
实现一个输入考试分数,打出评分,规则如下:
A: 90–100
B: 80–89
C: 70–79
D: 60–69
F: < 60
shell脚本实现:
#!/bin/sh
# Author: TZ edu
# 终端输入处理
read -p "请输入您的分数(0-100):" grade
# 合法性校验
if [ -z "$grade" ]; then
echo "您没有输入分数"
exit
fi
if [ $grade -gt "100" -o $grade -lt "0" ]; then
echo "您输入的分数不在0-100范围内"
exit
fi
# 计算等级
if [ $grade -ge "90" -a $grade -le "100" ]; then
echo "好极了,您的评分为: A"
elif [ $grade -ge "80" -a $grade -le "89" ]; then
echo "很好。您的评分为 B"
elif [ $grade -ge "70" -a $grade -le "79" ]; then
echo "好。您的评分为 C"
elif [ $grade -ge "60" -a $grade -le "69" ]; then
echo "不错。您的评分为 D"
elif [ $grade -lt "60" ]; then
echo "好吧。您的评分为 E"
fi
if语句实例结果
在这里插入代码片
循环 for 语法:
for item in …; do
…
done
for (( cond1; cond2; cond3 )) do
…
done
示例:
#!/bin/sh
# Author: TZ edu
echo "for循环示例1"
for ((i = 0; i < 5; i++)) do
echo $i
done
echo "for循环示例2"
for i in $(seq 5); do
echo $i
done
for示例结果
在这里插入代码片
while
语法:
while …; do
…
done
示例:
#!/bin/sh
# Author: TZ edu
echo "while循环示例"
i=5
while [ $i -gt 0 ]; do
echo $i
((i--))
done
while示例结果
在这里插入代码片
until
语法:
until …; do
…
done
示例:
#!/bin/sh
# Author: TZ edu
echo "until循环示例"
i=5
until [ $i -lt 0 ]; do
echo $i
((i--))
done
until示例结果
在这里插入代码片
选择
case
语法:
case var in
pattern 1 )
… ;;
pattern 2 )
… ;;
*)
… ;;
esac
示例:
#!/bin/sh
# Author: TZ edu
echo "case示例"
case $1 in
start | begin)
echo "start something";;
stop | end)
echo "stop something";;
restart)
echo "restart something"
;;
*)
echo "Ignorant"
;;
esac
case示例结果
在这里插入代码片
select
Bash提供了一种用于交互式应用的扩展select,用户可以从一组不同的值中进行选择。
语法:
select var in …; do
break;
done
示例:
#!/bin/sh
# Author: TZ edu
select ch in "begin" "end" "exit"; do
case $ch in
"begin")
echo "start something"
;;
"end")
echo "stop something"
;;
"exit")
echo "exit"
break;
;;
*)
echo "Ignorant"
;;
esac
done;
select示例结果
注意:这里交互输入要输入1,2,3,而不是beign,end,exit
函数
和其他语言一样,在Shell语言中也有着函数。尽管在Shell中函数并非是必须的编程元素,
但是通过使用函数,可以对程序进行更加好的组织。将一些相对独立的代码变成函数,
可以提高程序的可读性和重用性。避免重复编写大量相同的代码。
定义:
# 定义函数格式一:
functionname()
{
…
}
# 定义函数格式二:
# 函数名前面多了个function关键字
function functionname()
{
…
}
示例:
#!/bin/sh
# Author: TZ edu
# function用法示例
#####函数定义#####
# 注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。
# 无参数的函数定义
function hello(){
echo "Hello! "
}
# 有参数的函数定义
# $1为参数
function hello_param(){
echo "Hello $1 !"
}
# 有返回的函数定义
add(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
}
#####函数调用#####
echo "无参函数调用"
hello
echo "有参函数调用"
hello_param TZ edu
echo "有返回的函数调用"
add
# 函数返回值在调用该函数后通过 $? 来获得
echo "The sum of two numbers is $? !"
# 若函数与调用的地方不在同一个文件,在调用之前需要先加载
# .和文件名中间需要有个空格
# . filename.sh
# 另外,用unset functionname 可以取消载入指定的函数名
函数示例结果
二,shell编程应用
1.模拟linnux登录shell
#!/bin/bash
echo -n "login:"
read name
echo -n "password:"
read passwd
if [ $name = "cht" -a $passwd = "abc" ];then
echo "the host and password is right!"
else echo "input is error!"
fi
2.比较两个数大小
#!/bin/bash
echo "please enter two number"
read a
read b
if test $a -eq $b
then echo "NO.1 = NO.2"
elif test $a -gt $b
then echo "NO.1 > NO.2"
else echo "NO.1 < NO.2"
fi
3.查找/root/目录下是否存在该文件
#!/bin/bash
echo "enter a file name:"
read a
if test -e /root/$a
then echo "the file is exist!"
else echo "the file is not exist!"
fi
4.for循环的使用
#!/bin/bash
clear
for num in 1 2 3 4 5 6 7 8 9 10
do
echo "$num"
done
5…查看是否当前用户
#!/bin/bash
echo "Please enter a user:"
read a
b=$(whoami)
if test $a = $b
then echo "the user is running."
else echo "the user is not running."
fi
6.删除当前目录下大小为0的文件
#!/bin/bash
for filename in `ls`
do
if test -d $filename
then b=0
else
a=$(ls -l $filename | awk '{ print $5 }')
if test $a -eq 0
then rm $filename
fi
fi
done
7.如果/export/um_lpp_source下有文件,那么将其文件系统大小改为3G
#!/bin/bash
while line=`ls /export/um_lpp_source`
do
if test $line=""
then echo "NULL"
sleep 1
else echo $line
chfs -a size=3G /export/um_lpp_source
exit 0
fi
done
8.测试IP地址
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9
do
echo "the number of $i computer is "
ping -c 1 192.168.0.$i
done
9.如果test.log的大小大于0,那么将/opt目录下的*.tar.gz文件拷贝到当前目录下
#!/bin/sh
a=2
while name="test.log"
do
sleep 1
b=$(ls -l $name | awk '{print $5}')
if test $b -gt $a
then `cp /opt/*.tar.gz .`
exit 0
fi
done
10.打印读取的内容,为下面的例子做准备
#!/bin/bash
while read name
do
echo $name
done
11.从0.sh中读取内容并打印
#!/bin/bash
while read line
do
echo $line
done < 0.sh
12.读取a.c中的内容并做加1运算
#!/bin/bash
test -e a.c
while read line
do
a=$(($line+1))
done < a.c
echo $a
13.普通无参数函数
#!/bin/bash
p ()
{
echo "hello"
}
p
14.给函数传递参数
#!/bin/bash
p_num ()
{
num=$1
echo $num
}
for n in $@
do
p_num $n
done
15.创建文件夹
#!/bin/bash
while :
do
echo "please input file's name:"
read a
if test -e /root/$a
then
echo "the file is existing Please input new file name:"
else
mkdir $a
echo "you aye sussesful!"
break
fi
done
16.获取本机IP地址
#!/bin/bash
ifconfig | grep "inet addr:" | awk '{ print $2 }'| sed 's/addr://g'
17.查找最大文件
#!/bin/bash
a=0
for name in *.*
do
b=$(ls -l $name | awk '{print $5}')
if test $b -gt $a
then a=$b
namemax=$name
fi
done
echo "the max file is $namemax"
18.查找当前网段内IP用户,重定向到ip.txt文件中
#!/bin/bash
a=1
while :
do
a=$(($a+1))
if test $a -gt 255
then break
else
echo $(ping -c 1 192.168.0.$a | grep "ttl" | awk '{print $4}'| sed 's/://g')
ip=$(ping -c 1 192.168.0.$a | grep "ttl" | awk '{print $4}'| sed 's/://g')
echo $ip >> ip.txt
fi
done
19.打印当前用户
#!/bin/bash
echo "Current User is :"
echo $(ps | grep "$$" | awk '{print $2}')
20.case语句练习
#!/bin/bash
clear
echo "enter a number from 1 to 5:"
read num
case $num in
1) echo "you enter 1"
;;
2) echo "you enter 2"
;;
3) echo "you enter 3"
;;
4) echo "you enter 4"
;;
5) echo "you enter 5"
;;
*) echo "error"
;;
esac
21.yes/no返回不同的结构
#!/bin/bash
clear
echo "enter [y/n]:"
read a
case $a in
y|Y|Yes|YES) echo "you enter $a"
;;
n|N|NO|no) echo "you enter $a"
;;
*) echo "error"
;;
esac
22.内置命令的使用
#!/bin/bash
clear
echo "Hello, $USER"
echo "Today 's date id `date`"
echo "the user is :"
who
echo "this is `uname -s`"
echo "that's all folks! "
23.打印无密码用户
#!/bin/bash
echo "No Password User are :"
echo $(cat /etc/shadow | grep "!!" | awk 'BEGIN { FS=":" }{print $1}')