命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
_
。#定义string变量
string_var="hello world"
#定义数字变量
number_var=123
#显示 hello world
echo $string_var
#显示123
echo $nuber_var
#显示string_var
echo string_var
#本身不需要{},但是有时可以让编译器找出边界
echo ${string_var}oneworld
#删除变量
unset string_var
unset number_var
使用单引号的限制:
使用双引号的优点:
your_name="runoob"
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
#输出结果
Hello, I know you are "runoob"!
字符串的拼接
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
#使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
#输出结果为
hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !
获取字符串长度
string="abcd"
echo ${#string} # 输出 4
提取字符串
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找字符串
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
定义数组
#定义数组
array_name1=(value0 value1 value2 value3)
array_name2=(
value0
value1
value2
value3
)
#单独定义数组
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
#读取数组
value1=${array_name[1]}
# 用@符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
#取得数组元素的个数
length=${#array_name[@]}
#或者
length=${#array_name[*]}
#取得数组单个元素的长度
lengthn=${#array_name[n]}
两种办法,一种是使用$()
,另一种使用反引号``
a=$(ls)
echo a
a=`ls`
echo a
管道的符号是|
,表示将之前的命令的标准输出给到下一个命令的标准输入去,例如最常用的
ps -ef | grep virtuoso | grep ring_lu
这里的ps
表示列出进程,-e
表示列出所有进程,-f
表示以full format的形式输出。grep PATTERN [FILE]
本身是一个查找命令,输出名字为FILE
的文件内包含PATTERN
的行,这里的FILE
也可以是标准输出。
基本用法,函数名前的function
可以不加
function funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
函数的输入
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
在Bash shell中,函数可以返回多个值。但是,Bash shell的return命令只能返回数字,并且只能返回0到255之间的整数。如果一定要让函数返回一个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地方通过访问全局变量,就可以获得那个函数“返回”的一个或多个执行结果了 12。
如果您想要在函数中返回多个值,可以使用echo命令。在函数中使用echo命令输出多个值,然后在调用该函数时使用命令替换来捕获这些值。例如:
#!/bin/bash
function myfunc() {
local myresult='some value'
echo $myresult
return 0
}
result=$(myfunc)
=
两边不能使用空格,如#if与[之间需要空格,因为时命令
#[与"abc"之间需要空格,因为[]本质时一个test命令
#等号=两边需要空格,否则bash会将"abc"="abc"看成一个整体,直接反馈bool=true
if [ "abc" = "abc" ]; then echo ok;fi
#写成脚本
if condition
then
command1
command2
...
commandN
fi
#写成terminal中的命令行,单行模式
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
#if else 语法
if condition
then
command1
command2
...
commandN
else
command
fi
#if elif 语法
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
#if else 的 [...] 判断语句中大于使用 -gt,小于使用 -lt。
if [ "$a" -gt "$b" ]; then
...
fi
#如果使用 ((...)) 作为判断语句,大于和小于可以直接使用 > 和 <。
if (( a > b )); then
...
fi
#脚本中的写法
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
#写成一行
for var in item1 item2 ... itemN; do command1; command2… done
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
case ... esac
为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分支选择结构,每个 case
分支用右圆括号开始,用两个分号 ;;
表示 break,即执行结束,跳出整个 case ... esac
语句,esac
(就是 case
反过来)作为结束标记。
可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case
工作方式如下所示,取值后面必须为单词 in
,每一模式必须以右括号结束。取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;
。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 *
捕获该值,再执行后面的命令。
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
下面的脚本匹配字符串:
site="runoob"
case "$site" in
"runoob") echo "菜鸟教程"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac
break
命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
continue
命令与 break
命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改,运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo "游戏结束"
永远不会被执行。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
包含,注意这个字符不是常用的单引号,在 Esc 键下边。[$a==$b]**
是错误的,必须写成 [ $a == $b ]
。运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false |
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg”
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符用于检测 Unix 文件的各种属性。属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
-S file | 判断某文件是否 socket。 | |
-L file | 检测文件是否存在并且是一个符号链接。 |
每个文件打开时,都会产生以上3个文件,地址在 /proc/PID/fd
,使用>
或者>>
的可以将输出重定向到某个文件,默认只会重定向标准输出,
0
1
2
#将ls -a的标准输出结果输出到output.t中,以write形式写入文件,会覆盖原来的output.t
ls -a > ./output.t
#将ls -a的标准输出结果输出到output.t中,以append形式写入文件,附在output.t之后
ls -a >> ./output.t
#这里将执行结果重定向后,又将标准错误定向到标准输出中,这样output.t中既有stdout,也有stderr
#这里的&符号表示&1时一个文件描述符,而不是一个叫1的文件
ls -a >> ./output.t 2>&1
#需要丢弃的一些文件,可以写成,注意2与>之间不能有空格
ls -a 1> ./output.t 2>/dev/null
#使用"#"单行注释
#ls -a
#echo "helo word"
#多行注释,这里的EOF也可以使用其它符号或者字母,如',如!
:<<EOF
ls -a
echo "hello word"
EOF
:<<'
ls -a
echo "hello word"
'