shift位置参数左移、函数、退出循环
Shift位置参数左移指令
- shift命令用于对位置参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理。
- 每执行一次,位置参数序列顺次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数。
[root@nfs2 ~]# cat shift.sh
#!/bin/bash
if [ $# -le 0 ];then
echo "没有提供足够的参数"
exit 1
fi
sum=0
while [ $# -gt 0 ];do
sum=$(expr $sum + $1)
shift
done
echo “result is $sum”
[root@nfs2 ~]# sh shift.sh
没有提供足够的参数
[root@nfs2 ~]# sh shift.sh 1 2 3
“result is 6”
[root@nfs2 ~]# sh shift.sh 1 2 3 -4
“result is 2”
[root@nfs2 ~]# sh -x shift.sh 1 3 5 10 20
+ '[' 5 -le 0 ']'
+ sum=0
+ '[' 5 -gt 0 ']'
++ expr 0 + 1
+ sum=1
+ shift
+ '[' 4 -gt 0 ']'
++ expr 1 + 3
+ sum=4
+ shift
+ '[' 3 -gt 0 ']'
++ expr 4 + 5
+ sum=9
+ shift
+ '[' 2 -gt 0 ']'
++ expr 9 + 10
+ sum=19
+ shift
+ '[' 1 -gt 0 ']'
++ expr 19 + 20
+ sum=39
+ shift
+ '[' 0 -gt 0 ']'
+ echo “result is 39”
“result is 39”
- shift 位置参数的左移: shift [n]: n是个正整数,表示位置参数左移的个数
[root@nfs2 ~]# cat shift1.sh
#!/bin/bash
echo "First and Seconde pos argu:$1"
shift
echo "Third pos argu: $1"
[root@nfs2 ~]# sh shift1.sh 100 900
First and Seconde pos argu:100
Third pos argu: 900
[root@nfs2 ~]# cat shift1.sh
#!/bin/bash
echo "First and Seconde pos argu:$1,$2"
shift 2
echo "Third pos argu: $1"
[root@nfs2 ~]# sh shift1.sh 100 110 200
First and Seconde pos argu:100,110
Third pos argu: 200
函数的使用
- 函数是一个脚本代码块,你可以对它进行自定义命名,并且可以在脚本中任意位置使用这个函数,要使用这个函数,只要使用这个函数名称就可以了
函数:把一个功能封装起来。使用时直接调用函数名。这样的脚本好处:模块化,代码可读性强。
函数创建
function name() {
命令序列
[return value]
}
name() {
命令序列
[return value]
}
函数的使用
[root@nfs2 ~]# cat fun-1.sh
#!/bin/bash
# using a function in a script
function func1() { #定义函数
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1 #调用函数
# count=$(expr $count + 1)
let count++
done
echo "This is the end of the while"
func1 #调用函数
echo "Now this is the end of the script"
[root@nfs2 ~]# sh fun-1.sh
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is the end of the while
This is an example of a function
Now this is the end of the script
- 函数返回值:函数的退出状态
默认情况下,函数的退出状态是函数的最后一条命令返回的退出状态。
[root@nfs2 ~]# cat fun-2.sh
#!/bin/bash
# testing the exit status of a function
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function:"
func1
echo "The exit status is: $?"
[root@nfs2 ~]# sh fun-2.sh
testing the function:
trying to display a non-existent file
ls: cannot access badfile: No such file or directory
The exit status is: 2
- 函数返回值:return命令返回特定的退出码
return命令可以使用单个整数值来定义函数退出状态,提供了一种通过编程设置函数退出状态的简单方法。
注:return语句返回一个退出值给调用函数的程序,而exit的返回值是给执行程序当前的SHELL
[root@nfs2 ~]# sh fun-3.sh
ls: cannot access badfile: No such file or directory
result is 2
[root@nfs2 ~]# cat fun-3.sh
#!/bin/bash
fun1(){
ls badfile
return 2
echo "This is apple"
return 5
}
fun1
echo result is $?
[root@nfs2 ~]# sh fun-3.sh
ls: cannot access badfile: No such file or directory
result is 2
- 码必须要在函数一结束就进行取值。
- 码的取值范围(0~255)
把函数值赋给变量使用
- 函数的输出也可以捕获并存放到 shell 变量中。
[root@nfs2 ~]# cat fun-4.sh
#!/bin/bash
fun1(){
read -p "Input a value: " VAR
echo $[ $VAR * 5 ]
}
NUM=$(fun1)
echo current num is $NUM
[root@nfs2 ~]# sh -x fun-4.sh
++ fun1
++ read -p 'Input a value: ' VAR
Input a value: 5
++ echo 25
+ NUM=25
+ echo current num is 25
current num is 25
向函数传递参数
- 函数可以使用位置参数变量来表示要传递给函数的参数。
函数名在变量 $0 中定义, 函数命令行的其他参数使用变量 $1、$2..., $#可以用来确定传递给函数的参数数目。
- 第一种情况
[root@nfs2 ~]# cat fun-5.sh
#!/bin/bash
function addem() {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo "error,need to input one or two number."
elif [ $# -eq 1 ]
then
echo $(expr $1 + $1)
else
echo $(expr $1 + $2)
fi
}
echo -n "Adding 10 and 15: "
value=`addem 10 15`
echo $value
echo -n "Let's try adding just one number: "
value=`addem 10`
echo $value
echo -n "Now trying adding no numbers: "
value=`addem`
echo $value
echo -n "Finally, try adding three numbers: "
value=`addem 10 15 20`
echo $value
[root@nfs2 ~]# sh fun-5.sh
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no numbers: error,need to input one or two number.
Finally, try adding three numbers: error,need to input one or two number.
- 第二种情况
- 函数无法从脚本命令行(shell提示符中)直接访问脚本参数值。如果想在函数中使用这些值,那么必须在调用该函数时手动传递这些数据。
[root@nfs2 ~]# cat fun-6.sh
#!/bin/bash
# trying to access script parameters inside a function
function func6 {
echo $(expr $1 \* $2)
}
if [ $# -eq 2 ]
then
value=`func6 $1 $2`
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
[root@nfs2 ~]# sh fun-6.sh 4 6
The result is 24
[root@nfs2 ~]# sh -x fun-6.sh 4 6
+ '[' 2 -eq 2 ']'
++ func6 4 6
+++ expr 4 '*' 6
++ echo 24
+ value=24
+ echo 'The result is 24'
The result is 24
跳出循环
- 语句进行循环的过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell提供了两个命令来实现该功能:break和continue
注:exit:退出当前整个脚本的
[root@nfs2 ~]# cat break.sh
#!/bin/bash
while true
do
read -p "Enter a number [1-5]:" num
case $num in
1|2|3|4|5)
echo "GREATER"
;;
*)
echo "wrong...Bye"
break
esac
done
[root@nfs2 ~]# sh break.sh
Enter a number [1-5]:1
GREATER
Enter a number [1-5]:2
GREATER
Enter a number [1-5]:3
GREATER
Enter a number [1-5]:4
GREATER
Enter a number [1-5]:5
GREATER
Enter a number [1-5]:33
wrong...Bye
- 它和break命令差不多,忽略本次循环剩余的代码,直接进行下一次循环;在for、while等循环语句中,用于跳出当次循环,直接进入下一次循环。
[root@nfs2 ~]# cat continue.sh
#!/bin/bash
while true
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*)
echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
[root@nfs2 ~]# sh continue.sh
Input a number between 1 to 5: 1
Your number is 1!
Input a number between 1 to 5: 2
Your number is 2!
Input a number between 1 to 5: 3
Your number is 3!
Input a number between 1 to 5: 4
Your number is 4!
Input a number between 1 to 5: 5
Your number is 5!
Input a number between 1 to 5: 33
You do not select a number between 1 to 5!
Input a number between 1 to 5: 1
Your number is 1!
Input a number between 1 to 5: 2
Your number is 2!
Input a number between 1 to 5: ^C
[root@nfs2 ~]# cat add_user.sh
#!/bin/bash
while true
do
read -p "Please enter prefix & passwd & number: " pre pass num
printf "user information:
***********************
user prefix: $pre
user password: $pass
user number: $num
"
read -p "Are you sure?[y/n] " action
if [ "$action" == "y" ];then
break
fi
done
#adduser
for i in $(seq -w $num)
do
user=${pre}${i}
id $user &> /dev/null
if [ $? -ne 0 ];then
useradd $user
echo "$pass"|passwd --stdin $user &> /dev/null
if [ $? -eq 0 ];then
echo -e "\e[31m$user\e[0m create"
fi
else
echo "User $user exist"
fi
done
[root@nfs2 ~]# sh add_user.sh
Please enter prefix & passwd & number: aabc 123 10
user information:
***********************
user prefix: aabc
user password: 123
user number: 10
Are you sure?[y/n] y
aabc01 create
aabc02 create
aabc03 create
aabc04 create
aabc05 create
aabc06 create
aabc07 create
aabc08 create
aabc09 create
aabc10 create