shell 简单介绍
shell 是一个用 C语音编写的程序,它是用户使用linux 访问操作系统内核的桥梁,比如说
windows系统,它就是一个图形化的shell程序,点击图形化的界面去与操作系统打交道,windows 的 cmd窗口,也提供了shell 命令来操作 windows系统
那么对于linux来说,大部分还是使用shell 命令来操作 linux系统的。
简单来说 shell 就是命令解释器,将用户输入的指令进行解释成为内核可以识别的机器语言0101字符,然后内核在来调用硬件,硬件返回调用结果,还是由shell 解释器 来解析,返给用户最终结果
shell 环境
shell 编程 跟javaScript ,php 一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
不过经常用的是 Bourne Again Shell(/bin/bash) 由于易用和免费,被广泛使用,同时也是大部分linux系统默认的 shell
在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
注意事项解决办法:执行shell脚本报/bin/bash^M: bad interpreter(原因:脚本在windows 下编写的,到linux下,换行符号不同,导致linux不识别)
相关问题详情连接 错误详情直通车
sed -i 's#\r$##g' test.sh
还有一种解决方法 ,安装这个
yum -y install dos2unix
然后执行:将windows 下的dos 符号,转换为 linux 的
dos2unix 报错的文件名
第一个shell脚本
使用 touch test.sh 新建一个文件,linux 文件的扩展名并不直接影响文件的执行(扩展名只是为了便于人去分辨这个文件的类型,比如 test.sh 可以执行,你把文件名改为 test.text 然后去执行,也是可以执行的)
shell 脚本 第一行 永远以 #!/bin/bash 或者 #!/bin/sh
创建 好 test.sh 脚本文件后,进行授权才可以执行使用命令 chomd 来授权,
777 代表 当前用户可读可写可执行
chomd 777 ./test.sh
shell 变量使用
#!/bin/bash
echo '你好shell脚本'
#定义一个变量
name="liuyanjun"
#使用变量 可以不加$ 但是建议加上,加花括号是为了帮助解释器识别变量的边界
echo "我的名字叫 ${name}"
#不加花括号,例如这种情况,会将name 当作字符串输出,!!!加花括号是为了帮助解释器识别变量的边界
echo "我的名字叫 name"
# 已经定义的变量可以被重新定义
name="德玛西亚"
echo "我的名字叫${name}"
#只读变量 使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
#定义一个只读变量
readonly content="这是一个单纯的少年,单纯的我"
#然后尝试改变content的值,发现会报错:./test.sh: line 25: content: readonly variable
content="单纯的小三,单纯的她"
echo ${content}
# 删除变量 使用 unset 命令可以删除变量 语法:
#变量被删除后,不能再次使用,它不会生效的,会输出一个空白行,unset 命令不能删除只读变量
age="18"
echo ${age}
unset age
echo ${age}
输出结果
[root@VM-0-6-centos shell]# ./test.sh
你好shell脚本
我的名字叫 liuyanjun
我的名字叫 name
我的名字叫德玛西亚
./test.sh: line 27: content: readonly variable
这是一个单纯的少年,单纯的我
18
注意!,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找
shell 字符串
#!/bin/bash
name="LIUYANJUN"
str="${name} 是一个单纯的少年"
echo ${str}
#获取字符串的长度 语法: ${#这里写你变量的名称}
echo ${#str}
#截取字符串 在字符串 str截取 从 3下标开始,截取六位
echo ${str:3:6}
# 查找字子字符串,返回下标,发现英文返回的下标正确,中文不正确,不知道什么原因
echo `expr index "$str" 是`
echo `expr index "$str" I`
输出结果 查找子字符串 中文返回的下标不对,不知道什么原因
[root@VM-0-6-centos shell]# ./str.sh
LIUYANJUN 是一个单纯的少年
18
YANJUN
11
2
shell数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割,注意!!!用空格来分割数组中的元素,不是逗号哦!!!
#!/bin/bash
#在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开
#定义一个数组 注意 !!! 数组 元素与元素之间不要加逗号 用空格分割 ,这和大部分语言都不一样
arr=("小新" "阿呆" "妮妮" "小撤")
#输出数组中某个下标元素
echo ${arr[2]}
#输出数组中所有元素
echo ${arr[@]}
#获取数组的长度
echo ${#arr[@]}
#获取数组中 指定下标 单个元素的长度
echo ${#arr[2]}
输出结果
[root@VM-0-6-centos shell]# ./arr2.sh
妮妮
小新 阿呆 妮妮 小撤
4
2
Shell 数组的循环
#!/bin/bash
#在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开
#定义一个数组 注意 !!! 数组 元素与元素之间不要加逗号 用空格分割 ,这和大部分语言都不一样
#数组的第一个元素,使用变量代替
name="蜡笔小新"
arr=(${name} "阿呆" "妮妮" "小撤")
echo "输出数组中所有元素 ${arr[@]}"
echo "=====使用for循环遍历shell数组======i 代表数组中每一个元素,======> ${arr[@]} 代表数组中所有元素"
#语法很像java 中的增强for 循环
for i in ${arr[@]}
do
echo ${i}
done
# while 循环的演示,思路 其实就是 普通while 中 i++的形式,条件不成立的时候,就不会进入循环
echo "======使用while 循环 一直++ 当条件不成立时结束循环 关键词 let 来++,注意! while [] 内外边距一定要有空格"
j=0
while [ ${j} -lt ${#arr[@]} ]
do
echo ${arr[${j}]}
let j++
done
输出结果
[root@VM-0-6-centos shell]# ./arr2.sh
输出数组中所有元素 蜡笔小新 阿呆 妮妮 小撤
=====使用for循环遍历shell数组======i 代表数组中每一个元素,======> 蜡笔小新 阿呆 妮妮 小撤 代表数组中所有元素
蜡笔小新
阿呆
妮妮
小撤
======使用while 循环 一直++ 当条件不成立时结束循环 关键词 let 来++,注意! while [] 内外边距一定要有空格
蜡笔小新
阿呆
妮妮
小撤
Shell 传递参数
在执行脚本的时候,我们可以从外界给脚本传递参数,规则为:$n n代表一个数字(代表你脚本中 接收外界传过来的第几个参数) $2 代表接收外界传过来的第2个参数 $ 5 代表接收 传过来的第5个参数。。。。类似这种
具体看这个示例 :脚本很简单,接收控制台传过来的五个参数
刚开始我是按照 $1 $2 $3 $4 $5 这样顺序传参的,结果输出的也是和我传递的参数 顺序一致,为了测试,将 $1 和 $5 互换,会发现 值也跟着变化了
#!/bin/bash
echo "=======shell 脚本参数传递学习========"
echo $5
echo $2
echo $3
echo $4
echo $1
输出结果
第一次输出为:$1 $2 $3 $4 $5 第二次: 将 $1 和 $5 互换
[root@VM-0-6-centos shell]# ./parameter.sh 小新 阿呆 妮妮 小撤 正雄
=======shell 脚本参数传递学习========
小新
阿呆
妮妮
小撤
正雄
[root@VM-0-6-centos shell]# ./parameter.sh 小新 阿呆 妮妮 小撤 正雄
-bash: ./parameter.sh: /bin/bash^M: bad interpreter: No such file or directory
[root@VM-0-6-centos shell]# sed -i 's#\r$##g' parameter.sh
[root@VM-0-6-centos shell]# ./parameter.sh 小新 阿呆 妮妮 小撤 正雄
=======shell 脚本参数传递学习========
正雄
阿呆
妮妮
小撤
小新
[root@VM-0-6-centos shell]#
结论 :在运行脚本的时候 , 可以接收参数,规则为:$n n 为一个数字 ,代表接收传过来的第几个参数
另外记录一下几个特殊 字符
$# 代表一共传递了多少个参数
$* 将传递的所有参数 作为一个整体(相当于传入一个参数) 输出
$@ 将传递的所有参数 作为一个整体(实际上还是传入了多个参数) 输出
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
$* 与 $@ 区别
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,
则 " * " 等价于 “1 2 3”(传递了一个参数),
而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
看案例:使用 for循环去看 ∗ 和 * 和 ∗和@ 发现输出不一样
echo "===========使用======'$*'======= 演示"
for i in "$*"
do
echo $i
done
echo "======使用'$@'===== 演示"
for i in "$@"
do
echo $i
done
输出结果:for循环可以看出 $* 是一个 $@ 是多个
===========使用======'$*'======= 演示
小新 阿呆 妮妮 小撤 正雄
======使用'$@'===== 演示
小新
阿呆
妮妮
小撤
正雄
Shell 运算符
运算符 关键字 expr 举例
注意事项!!!使用 关键字 expr 并且 使用反引号 符号和变量之间要有空格
注意乘法 很特别 *
!!! 赋值 =两边不能有空格,会报错
#!/bin/bash
a=10
b=20
echo "a加b=" `expr $a + $b`
jian=`expr $b - $a`
echo "b减a=" ${jian}
chen=`expr $a \* $b`
echo “a乘以 b=” ${chen}
chu=`expr $b / $a`
echo “b除以a=” ${chu}
quyu=`expr $b % $a`
echo "b取余a= ${quyu}"
#b的值赋值给a =号两边不能有空格,会报错
a=$b
echo ${a}
#等于和不等于的运算 true false
if [ $a == $b ]
then
echo "a等于b"
elif [ $a != $b ]
then
echo "a不等于b"
fi
输出结果,因为上面将 b的值赋值给a 所有为true,输出 a等于b
[root@VM-0-6-centos shell]# ./ys.sh
a加b= 30
b减a= 10
“a乘以 b=” 200
“b除以a=” 2
b取余a= 0
20
a等于b
shell 关系用算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20
运算符 说明 举例
-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。
例如
echo "=========关系运算符=======只支持数字运算"
c=100
if [ $a -eq $c ]
then
echo "a等于c"
else
echo "a不等于b"
fi
输出结果,其它运算符 同理
=========关系运算符=======只支持数字运算
a不等于b
shell布尔运算符
! 不等于
-o 类似java 中的 或 ||
-a 类型java 中的 并且 &&
下表列出了常用的布尔运算符,假定变量 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。
案例:用 -o 或 来举例 剩下 -a 同理
#!/bin/bash
a=100
b=60
c=60
if [ $a -eq $b -o $b -eq $c ]
then
echo "其中一个条件成立,执行if"
else
echo "条件不成立,执行else"
fi
输出结果
[root@VM-0-6-centos shell]# ./buer.sh
其中一个条件成立,执行if
shell逻辑运算符
逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true
shell字符串运算符
a="蜡笔小新" b="妮妮"
运算符 说明 举例
= 检测两个字符串是否相等,相等返回 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。