一、 Shell基础知识
在 Xshell 中,常量和变量的表示方法如下:
- 常量表示: 常量是直接给出的固定值,不需要进行特别表示。你可以直接在命令行中输入常量值,如字符串、数字等。
- 变量表示: 变量用于存储和操作数据。在 Xshell 中,可以使用
$
符号后跟变量名来表示一个变量。例如,$str
表示名为str
的变量。
二、基本命令
循环数字
for(i=1;i<=10;i++);
do
echo $(expr $i \* 3 + 1)
done
for i in {1..10}
do
echo $(expr $i \* 3 + 1)
done
结果:4 7 10 13 16 19 22 25 28 31
循环字符
for i in an zhi qiang
do
echo $i
done
结果:an zhi qiang
循环List
list="rootfs usr data data2"
for i in $list
do
echo $i is appoint
done
结果:
rootfs is appoint
usr is appoint
data is appoint
data2 is appoint
$0:表示当前文件名
$1:可以指定传参数
echo "shell 传参数示例"
echo "执行文件名:$0"
echo "第一个参数:$1"
三、运算
算数运算
a=$1
b=$2
g=`expr $a + $b`
echo "$g"
翻译:
- $1、$2是引用变量,外部传入的
- 算数也运算要用
expr XXX
- 输出 $g 这个是C/Java使用无歧义
逻辑运算
# if
if [ $a = $b ]
then
echo "a等于b"
fi
# if-else
if[ $a != $b ]
then
echo "a不等于b”
else
echo "a等于b"
fi
# if-else-if
if [ $a == $b ]
then
echo "a不等于b”
elif [$ a -gt $b]
then
echo "a大于b"
elif [$ a -ltl $b]
then
echo "a小于b"
else #一定要补充else
echo "数据不符合条件"
fi
then fi 相当于if中的 {}
字符串使用
#!/bin/bash
username="robert"
# 使用双引号拼接
greeting_0="hello, "$username" !"
greeting_1="hello, $username !"
echo $greeting_0 $greeting_1
# 使用单引号拼接
greeting_2='hello, '$username' !'
greeting_3='hello, $username !'
echo $greeting_2 $greeting_3
# 获取字符串的长度
str="I come from china!"
echo -e "$str 的长度为 ${#str}"
# 截取子字符串
sub_str=${str:3:9} #从3位置之后开始,截取9个长度的字符串
echo $sub_str
# 查询字符串(第一次出现的位置)
echo `expr index "$str" china`
echo `expr index "$str" from`
echo `expr index "$str" I`
echo `expr index "$str" i`
echo `expr index "$str" m`
# 结果
hello, robert ! hello, robert !
hello, robert ! hello, $username !
I come from china! 的长度为 18
ome from
3
4
1
15
5
${#str} - 表示获取字符串str的长度。
三、数组
daiyi_array=(12 34.5 "china" 'A' G daiyi)
echo "daiyi_array[0]=${daiyi_array[0]}"
echo "daiyi_array[1]=${daiyi_array[1]}"
echo "daiyi_array[2]=${daiyi_array[2]}"
echo "daiyi_array[3]=${daiyi_array[3]}"
echo "daiyi_array[4]=${daiyi_array[4]}"
echo "daiyi_array[5]=${daiyi_array[5]}"
echo "daiyi_array[6]=${daiyi_array[6]}"
echo "daiyi_array[1000]=${daiyi_array[1000]}"
echo "daiyi_array[-1]=${daiyi_array[-1]}"
echo "daiyi_array[-4]=${daiyi_array[-4]}"
printf "输出全部数组元素\r\n"
# 输出全部数组元素
echo ${daiyi_array[*]}
echo "------------------------------------"
printf "输出全部数组元素(地址)\r\n"
# 输出全部数组元素(地址)
echo ${daiyi_array[@]}
echo "------------------------------------"
结果:
dayi_arrys includs for 12
daiyi_array[0]=12
daiyi_array[1]=34.5
daiyi_array[2]=china
daiyi_array[3]=A
daiyi_array[4]=G
daiyi_array[5]=daiyi
daiyi_array[6]=
daiyi_array[1000]=
daiyi_array[-1]=daiyi
daiyi_array[-4]=china
------------------------------------
输出全部数组元素
12 34.5 china A G daiyi
------------------------------------
输出全部数组元素(地址)
12 34.5 china A G daiyi
------------------------------------
含义:
- 数组输出表达式:${数组名[Index]}
- 数组表达式:数组(X X XX XX)。中间用空格隔开,字符用 “”。
- 输出数组全部内容。例如:
${daiyi_array[*]}
- 输出全部属于元素(地址)。例如:
${daiyi_array[@]}
${array[@]}
和${array[*]}
都被用来打印数组的所有元素。- 如果数组是空的,${array[@]} 不会有任何输出
数组遍历(for)
printf "for循环遍历索引 index\r\n"
# for循环遍历索引 index
for i in 0 1 2 3 4 5
do
echo "daiyi_array[$i]=${daiyi_array[$i]}"
done
echo "------------------------------------"
printf "输出数组长度\r\n"
# 输出数组长度
echo "数组元素的个数:${#daiyi_array[*]}"
echo "------------------------------------"
for循环遍历索引 index
daiyi_array[0]=12
daiyi_array[1]=34.5
daiyi_array[2]=china
daiyi_array[3]=A
daiyi_array[4]=G
daiyi_array[5]=daiyi
------------------------------------
输出数组长度
数组元素的个数:6
------------------------------------
# 的含义:截至目前为止所表达的意思时长度的意思。
daiyi_array=(12 34.5 "china" 'A' G daiyi)
# for循环遍历数组中的元素
for daiyi in ${daiyi_array[*]} #@地址
do
echo $daiyi
done
echo "------------------------------------"```
# while循环遍历数组的索引来访问元素
i=0
while(($i<${#daiyi_array[*]}))
do
echo "daiyi_array[$i]=${daiyi_array[$i]}"
let "i++"
done
# i=0 第五次就结束了
12
34.5
china
A
G
daiyi
关联数组
在shell中,没有内置的关联数组(associative array)类型。通常,我们使用普通的索引数组来存储和操作键值对。然而,通过使用一些技巧和扩展,我们可以模拟关联数组的行为。
一种常见的方法是使用declare
命令将数组的索引定义为字符串类型,然后将键作为索引来访问相应的值。以下是一个示例:
#!/bin/bash
# 声明一个关联数组
declare -A myArray
# 添加键值对到关联数组
myArray["key1"]="value1"
myArray["key2"]="value2"
# 访问关联数组中的值
echo "Value for key1: ${myArray["key1"]}"
echo "Value for key2: ${myArray["key2"]}"
在上面的示例中,declare -A
用于声明一个关联数组myArray
。然后,我们使用myArray["key"]="value"
的语法将键值对添加到数组中。通过使用键来索引数组,我们可以访问关联数组中的值。
请注意,这只是一种模拟关联数组的方法,而不是真正的关联数组实现。在更高级的编程语言中,通常有更复杂的数据结构来支持关联数组。
数组声明:declare -A XXX
< K - Y >
对应的形式为XXX[“K”]=“V”
#!/bin/bash
printf "关联数组(<key,value>)\r\n"
# 关联数组(<key,value>)
declare -A my_array
my_array["baidu"]="http://wwww.baidu.com/"
my_array["google"]="http://www.google.com/"
my_array["tmall"]="http://www.tmall.com/"
my_array["jd"]="http://www.jd.com/"
echo ${my_array["tmall"]}
echo ${my_array["baidu"]}
echo "------------------------------------"
printf "输出全部数组元素\r\n"
# 输出全部数组元素
echo ${my_array[*]}
echo "------------------------------------"
printf "输出全部数组元素(地址)\r\n"
# 输出全部数组元素(地址)
echo ${my_array[@]}
echo "------------------------------------"
printf "输出数组长度\r\n"
# 输出数组长度
echo "数组元素的个数:${#my_array[*]}"
echo "------------------------------------"
printf "for循环遍历键key \r\n"
# for循环遍历键key
for i in baidu tmall jd google 163
do
echo "my_array[$i]=${my_array[$i]}"
done
echo "------------------------------------"
printf "输出数组中全部key \r\n"
# 输出数组中全部key
# for循环遍历键key
for i in ${!my_array[*]}
do
echo "my_array[$i]=${my_array[$i]}"
done
echo ${!my_array[@]}
结果:
关联数组(<key,value>)
http://www.tmall.com/
http://wwww.baidu.com/
------------------------------------
输出全部数组元素
http://www.tmall.com/ http://www.google.com/ http://wwww.baidu.com/ http://www.jd.com/
------------------------------------
输出全部数组元素(地址)
http://www.tmall.com/ http://www.google.com/ http://wwww.baidu.com/ http://www.jd.com/
------------------------------------
输出数组长度
数组元素的个数:4
------------------------------------
for循环遍历键key
my_array[baidu]=http://wwww.baidu.com/
my_array[tmall]=http://www.tmall.com/
my_array[jd]=http://www.jd.com/
my_array[google]=http://www.google.com/
my_array[163]=
------------------------------------
输出数组中全部key
my_array[tmall]=http://www.tmall.com/
my_array[google]=http://www.google.com/
my_array[baidu]=http://wwww.baidu.com/
my_array[jd]=http://www.jd.com/
tmall google baidu jd
-
${my_array[*]}
是用来获取数组中的所有元素。例如,如果 my_array 是一个包含 “apple”,“banana”,和 “cherry” 的数组,${my_array[*]} 将会返回 “apple”,“banana”,和 “cherry”。 -
${!my_array[*]}
是用来获取数组的所有索引。例如,如果 my_array 的索引是 0,1,和 2,那么 ${!my_array[*]} 将会返回 0,1,和 2。
read命令
Shell 中的 read 命令用于从标准输入(键盘)或其他文件描述符中读取数据。它可以将读取到的数据存储到指定的变量中,并支持一些参数来控制读取的行为。
read 命令的基本语法如下:
read [options] [variable]
这里的 [options]
是可选的,用于指定 read 命令的一些参数,例如超时时间、读取的字符个数等。[variable]
是用来存储读取到的数据的变量名。
以下是一些常用的 read 命令参数:
-a
:将分裂后的字段依次存储到指定的数组中。-d
:指定读取行的结束符号,默认为换行符。-n
:限制读取 N 个字符就自动结束读取。-N
:严格要求读满 N 个字符才自动结束读取。-p
:给出提示符,用于在读取前输出提示信息。-r
:禁止反斜线的转义功能。-s
:静默模式,输入的内容不会回显在屏幕上。-t
:给出超时时间,在达到超时时间时,read 退出并返回错误。
以下是一个简单的例子,演示了如何使用 read 命令读取用户输入的内容并存储到变量中:
#!/bin/bash
echo "请输入您的名字:"
read name
echo "您输入的名字是:$name"
在这个例子中,用户会被提示输入名字,然后输入的内容会被存储到变量 name
中,并输出到屏幕上。
示例:
# while循环(控制操作)
echo "按下 <ctrl-D> 退出"
echo -n "输入学生的姓名:"
while read sname
do
printf "%-5s同学,你好!欢迎返校!\r\n" $sname
echo -n "输入学生的姓名:"
done
until
# until循环(命令直到条件为true才终止循环)
a=0
until [ ! $a -lt 10 ] #解释当a不在小于10
do
echo $a
let "a++"
done
echo "-----------------------------------------"
b=0
while [ $b -lt 10 ] #条件满足时才会执行循环体
do
echo $b
let "b++"
done
区分until和while循环
在Bash脚本中,until循环会一直执行,直到给定的条件不再满足。
until循环是一种重复执行某个操作直到 满足特定条件 的方式。
然而,while循环则是当给定的条件满足时才会执行循环体内的命令,如果条件一开始就不满足,那么循环体内的命令将不会被执行。
如果初始条件不满足,Bash中的until循环将不会执行循环体内的任何命令
示例:
until [ $a -lt 10 ] #刚开始就是为true,直接绝结束了
do
echo $a
let "a++"
done
case语句
#!/bin/bash
# case用法
printf "输入1到4的整数:\r\n你输入的数字为:"
read num
case $num in
1) echo "数字:一"
;;
2) echo "数字:二"
;;
3) echo "数字:三"
;;
4) echo "数字:四"
;;
esac
echo "-----------------------------------"
web="baidu"
case "$web" in
"google") echo "url:http://www.google.com"
;;
"baidu") echo "url:http://www.baidu.com"
;;
"163") echo "url:http://www.163.com"
esac
结果:
输入1到4的整数:
你输入的数字为:1
数字:一
-----------------------------------
url:http://www.baidu.com
case…esac
四、函数
示例:
写法
default(){
# 函数体
}
调用
defaule #简单粗暴
带参函数:
#!/bin/bash
# 带参函数示例
greet() {
local name=$1 # 第一个参数
echo "Hello, $name!"
}
# 调用带参函数
greet "Alice" # 输出:Hello, Alice!
greet "Bob" # 输出:Hello, Bob!
加法示例1:
#!/bin/bash
# 带多个参数的函数示例
calculate() {
local num1=$1
local num2=$2
local result=$((num1 + num2))
echo "The sum is: $result"
}
# 调用带多个参数的函数
calculate 10 5 # 输出:The sum is: 15
加法示例2:
# 声明两数相加的求和函数
funSum(){
echo "a="
read a
echo "b="
read b
return $(($a + $b))
}
echo "-----funSum函数开始执行-----"
# 调用函数
funSum
echo "a+b= $?"
echo "-----funSum函数执行完毕-----"
return语句的返回值被存储在特殊变量$?中
#!/bin/bash
# 带参函数示例,添加了return语句
calculate() {
local num1=$1
local num2=$2
local result=$((num1 + num2))
echo "The sum is: $result"
# 返回计算结果
return $result
}
# 调用带参函数,并捕获返回值
sum=$(calculate 10 5)
echo "Returned value: $sum"
问: 为什么要在方法体内加入echo ,如果删除echo的话就没有输出
# 带多个参数的函数示例
calculate() {
local num1=$1
local num2=$2
local result=$((num1 + num2))
echo $result # 将结果输出出来,然后返回
return "$result"
}
# 调用带多个参数的函数
sum=$(calculate 10 5)
echo "Returned value: $sum"
在Shell函数中,echo
命令用于输出文本。在你的函数calculate
中,echo $result
是用来输出计算结果result
的值。
如果你在函数中删除echo $result
,函数将不会输出任何结果。这是因为result
的值没有被直接输出,而且return
语句返回的结果并没有被赋值给任何变量。在这种情况下,即使你调用了calculate
函数并将结果赋值给了变量sum
,sum
变量中也不会包含任何值。
为了在函数外部获得函数内部的计算结果,你需要在函数中使用echo
命令输出结果,并将输出结果赋值给一个变量。在你的代码中,echo $result
将输出result
的值,然后使用命令替换将输出结果赋值给变量sum
。这样,在函数外部,你就可以通过访问sum
变量来获取函数内部的计算结果。
因此,为了在函数外部获取函数内部的计算结果,你需要在函数中使用echo
命令来输出结果,并将输出结果赋值给一个变量。
带参数建议采用最后一种,用echo将值输出,然后返回。
可以使用$?
return语句的返回值被存储在特殊变量$?中
改的示例2:
# 带多个参数的函数示例
funSum(){
echo "a="
read a
echo "b="
read b
local result=$(($a + $b))
echo $result
return $result
}
echo "-----funSum函数开始执行-----"
# 调用函数
funSum
echo "a+b= $?"
echo "-----funSum函数执行完毕-----"
if [ "$?" == "0" ]