shell 脚本是个纯文本文件,命令从上而下,一行一行地开始执行。
shell 脚本第一行一定要为:#!/bin/bash
Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
本教程关注的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。
在一般情况下,人们并不区分
Bourne Shell和Bourne Again Shell,所以,像#!/bin/sh,它同样也可以改为#!/bin/bash。
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
#!/bin/bash
echo hello world! 执行权限chmod +x test.sh
shell定义变量时,变量名不加美元符号$
your_name="runoob.com" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样
使用一个定义过的变量,只要在变量名前面加美元符号即可
your_name="qinjx"
echo $your_name
echo ${your_name} 变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done 如果不给skill变量加花括号,写成echo “I am good at $skillScript”,解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`
或
for file in $(ls /etc) 只读变量
#!/bin/bash
myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com" 字符串可以用单引号,也可以用双引号,也可以不用引号。 单引号
str='this is a string' 单引号字符串的限制: 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号
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[0]} # 输出 4 运算符 | 说明 | 举例 |
|---|---|---|
= | 检测两个字符串是否相等,相等返回 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。 |
在 Shell 中,用括号来表示数组,数组元素用”空格”符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n) 如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
) 读取数组
${数组名[下标]}
如
valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
获取数组长度
length=${#array_name[@]}
# 或者
length=${#array_name[*]} #!/bin/bash
echo "please input name and your age:"
read name age #读取键盘输入字符串,赋值给变量 name 和 age
echo "your name:" $name ",your age: $age" 输入变量 name和age的时候中间的多余空格被忽略 如 xujinding 88(多个空格)和xujinding 88(一个空格)是一样的
shell 仅支持整型,数值计算使用$((表达式)),示例:
divided=$(($operand/$number)) #赋值等号间不能有空格 expr 是一款表达式计算工具,使用它能完成表达式的求值操作
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val" 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样 完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
# 乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi 注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的, 必须写成 [ $a == $b ]。
test命令用于查看文件是否存在、权限等信息,可以进行数值、字符和文件三方面的测试
判断文件是否存在
#!/bin/bash
read -p "please input file name: " filename
test -e $filename && echo "$filename exist" || echo "$filename non-existence"# test -e :如果文件存在则为真 字符串测试
cmd1 && cmd2
#当 cmd1 执行完毕且正确,那么 cmd2 执行,当 cmd1 执行完毕且错误,那么 cmd2 不执行
cmd1 || cmd2
#当 cmd1 执行完毕且正确,那么 cmd2 不执行,当 cmd1 执行完毕且错误,那么 cmd2 执行
#!/bin/bash
read -p "please input first string: " firstStr
read -p "please input second string: " secondStr
test $firstStr = $secondStr && echo "The two strings are the same" || echo "The two strings are not the same"
# test str1 = str2 :两个字符串相等则为真 $0~$n,表示 shell 脚本的执行参数,$1 为执行脚本的第一个参数,$2 为执行脚本的第二个参数,以此类推….其中 $0 为执行的文件名(包含文件路径)
$#表示最后一个参数的标号。
$@表示除$0外的所有参数。
#!/bin/bash
echo "The zero parameter :"$0
echo "The first parameter :"$1
echo "The second parameter:"$2
echo "The label of the last parameter:"$#
echo "All parameters :"$@ 
function fname(){ # function 可写可不写
# 函数代码段
}
fname #无参调用
# 函数调用 跟其他语言不一样 java是 fname(param1,param2)
fname param1 param2 # 函数传参
#!/bin/bash
fun1(){
echo "$0"
echo "param1:$1"
echo "param2:$2"
echo "$#"
echo "$@"
}
fun1 lcx1 lcx2 
返回值
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
这个函数会对输入的两个数字进行相加运算...
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 ! 函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
#!/bin/bash
for name in lcx1 lcx2 lcx3
do
echo "name = $name"
done
#!/bin/bash
for((count=0;count<=10;count++))
do
echo "$count"
done if 条件判断;then
# 判断成立后要执行的语句
fi # 结束语句
--------------------------------------------------------------------
if 条件判断; then
# 条件判断后成立要执行的语句
else
# 条件判断后不成立要执行的语句
fi
--------------------------------------------------------------------
if 条件判断; then
# 条件判断后成立要执行的语句
elif 条件判断;then # 此语句可多次添加
# 条件判断后成立要执行的语句
else
# 条件判断后不成立要执行的语句
fi
--------------------------------------------------------------------
case $变量 in # 与 C语言 switch case 相似
"第一个变量内容")
# 程序段
;; # 表示第一个程序块结束
"第二个变量内容")
# 程序段
;; # 表示第二个程序块结束
"第n个变量内容")
# 程序段
;; # 表示第 n个程序块结束
*) # 类似 C语言 switch case的 default
# 程序段
;;
esac