shell是一个用C语言编写的程序,是使用Liunx的桥梁。shel既是一种命令语言,又是一种设计语言,它提供一个界面(小黑屏),用户通过这个界面访问操作系统内核的服务。
在我们通常说的shell一般说的是shell script(shell脚本)。但学习者还是需要知道shell 和shell script两者是不同的概念。由于习惯问题,所以shell都是指shell脚本编写。
shell编程和JavaScript、PHP一样,除了文本编辑外就只需要一个能解释执行的脚本解释器就可以了。Linux的shell种类有很多,常见的有
shell脚本扩展名为sh
,但实际扩展名并不影响脚本执行,见名知意就好。
#!/bin/bash
echo "Hello World !"
文件开头说明
#! 是shell的约定标记,它告诉系统这个脚本需要什么解释器执行,#!/bin/bash 代表Bash方式执行。
授权为可执行程序
chmod +x ./test.sh #使脚本具有执行权限
执行
./test.sh # 或者指定解释器运行,这种方式不需要在第一行指定解释器信息,指定了也没用。
/bin/sh ./test.sh
test_name="xiaoMing"
变量名和等号之间不能有空格。
test_name="xiaoMing"
echo $your_name
# 推荐使用这个
echo ${your_name}
加大括号可以帮助解释器识别变量边界,所以推荐所有变量名都加上大括号,这是个编程的好习惯
test_name="xiaoMing"
readonly $your_name
如果将变量设置为只读,后面重新赋值,在运行时就是执行报错: /bin/sh: NAME: This variable is read only.
unset variable_name
运行shell时,会同事存在三种变量
局部变量
局部变量在脚本或者命令中定义,仅在当前shell实例中有效
环境变量
所有的程序,包含shell启动的程序,都能访问的环境变量
shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
str='123'
单引号里不能引用变量名,除非单引号里再嵌套个单引号里引用变量。并且不是出现一个单引号,除非成对出现,作为字符串拼接
hi="Hello World"
name="${hi} shenyao"
echo ${name}
使用双引号的优点
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"# 使用单引号拼接
greeting_2='hello, '$your_name' !'
string="abcd"
echo ${#string} # 输出 4
name="123";
name2=${name:0:2} //12
shell数组支持一维数组,并且没有限制数组的大小,可以通过索引访问元素。
直接声明
array_name=(value0 value1 value2 )array_name=('111' '2222 22' '3333')
换行
array_name=(
value0
value1
value2
)
可以单独定义各个值
array_name[0]=value0
array_name[1]=value2
不仅可以使用索引赋值,也可以用任意字符来关联元素
首先使用declare
关键字声明为关联数组
declare -A array_namearray_name["google"]="www.google.com"
array_name["runoob"]="www.runoob.com"
array_name["taobao"]="www.taobao.com"
${数组名[索引下标]}value=${array_name[0]}#@符号获取所有元素
values=${array_name[@]}
获取字符串长度时使用${#string}
,数组长度也类似使用#
length=${#array_name[@]}
#或者
length=${#array_name[*]}
在运行shell脚本时,有时我们需要在执行脚本时传递参数。脚本内获取参数的格式为:$n。n代表一个数字,其中$0代表里执行的文件名,从1开始才是真正传的参数,$1代表第一个传递的参数,$2代表第二个传递的参数
例如
#执行脚本
./test.sh 1 2 3# 脚本内容
#!/bin/bas
echo "shell 传递参数示例开始"
# 执行的文件名
echo "执行的文件名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"shell 传递参数示例开始
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
其他引用列表
参数 | 说明 |
---|---|
$# | 传递参数的个数 |
$* | 传递的所有参数 |
$$ | 脚本运行的当前进程ID号 |
$@ | 与$* 相同,但是传参的时候需要使用引号括起来,否则它就当成一个参数 |
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如:awk,expr,let最常用。
val=`expr 2 + 2`
注意
1、表达式何运算符质检要有空格,例如2+2是不对,要 2 + 2,2、表达式要用``包裹起来,
let s=(2+4)*4
注意
1、运算符和参数之间不能有空格
2、与expr对比,let命令更简洁直观
3、let使用位操作符<<
、>>
和&
需要用\
来转义
运算符 | 说明 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
= | 赋值 |
== | 判断相等,用于比较两个数字,相同返回true。只能用于数字类型且在if判断中使用 |
!= | 判断不相等,不相同则返回 true。 |
该运算符只支持数字
运算符 | 说明 |
---|---|
-eq | 检查两个数是否相等 |
-ne | 不相等 |
-gt | 大于 |
-lt | 小于 |
-ge | 大于等于 |
-le | 小于等于 |
运算符 | 说明 |
---|---|
! | 非运算,取反的作用 |
-o | 或运算,相当于` |
-a | 且运算,相当于& ,两个表达式为true才返回true |
运算符 | 说明 |
---|---|
&& | and |
|| | OR |
运算符 | 说明 |
---|---|
= | 两个字符串是否相等 |
!= | 是否不相等 |
-z | 长度是否为0 |
-n | 长度是否不为0 |
$ | 是否不为空 |
操作符 | 说明 |
---|---|
-d file | 文件是否是目录 |
-r file | 是否可读 |
-w file | 是否可写 |
-x file | 是否可执行 |
-s file | 是否为空 |
-e file | 文件(包含目录)存在 |
echo是一个输出命令,格式如下
echo string
获取控制台输入
read name
echo "${name} 你好"
执行后脚本,name变量作为控制台输入的变量
./test.sh
xiaoMing #控制台输入
xiaoMing 你好 #输出
printf和echo都是输出命令,但printf的脚本比echo移植性高。比如可以传参数
示例
printf "你好吗? %s \n" 小明#打印出来就是
你好吗? 小明
格式化输出
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
符号 | 说明 |
---|---|
%s | 替换符,s声明是字符串的意思 |
%-10s | 指定一个宽度为10个字符,-表示左对齐,没有则右对齐。不满10字符会自动空格值填充,超过也全部显示 |
%c | %c是输出一个字符 |
%f | 数字类型 |
%-5.3f | 数字类型,占5个字符,超过也展示,保留3位小数 |
if
判断里可以用[...]
和((...))
。 使用[...]
判断大小用-gt
和-lt
,使用((...))
可以用>
和<
if [条件]
then满足后执行命令
fi
if [条件]
thenecho '两个数字相等!'
elseecho '两个数字不相等!'
fi
if [条件1]
then满足条件1执行
elif [ 条件2 ]
then满足条件2执行
else都不满足执行
fi
for in 类型
for loop in 1 2 3 4 5
doecho "The value is: ${loop}"
done
array_name=('一' '二' '三')
for var in ${array_name[*]}
doecho "值为: ${var}"
done
for i 类型
fori 模式和其他编程语法差不多
array_name=('一' '二' '三')
for(( i=0;i<${#array_name[*]}; i++ ))
doecho "值为: ${array_name[i]}"
done
while [条件]
do执行命令
done
示例
#!/bin/basharray_name=('一' '二' '三')
num=${#array_name[*]}echo "长度为--> ${num}"
while [ ${num} -ge 0 ]
doecho "该值为:${array_name[${num}]}"let "num--"
done