Linux中shell语法和脚本编写
原文地址:学习shell的语法,及脚本编写
其它相关辅助资料:
编写shell脚本所需的语法和示例
基础linux指令&简单的shell语法和脚本编写
什么是shell脚本
1、shell是一个命令行解释器,是解释执行的脚本语言,在shell中可以直接调用linux系统命令。为用户提供了一个向linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动、挂起、停止甚至是编写一些程序(说白了就是一个解释器,拿这个写内核就认识,它就将我们编写的程序翻译成01010101…)
2、程序也就是计算机命令。输入指令回车之后,shell就会把这个命令通过对应的ascii码翻译成指定的机器语言,传递给内核。然后调用内核(硬件)来处理
我们操作的文字界面就是shell
指令是 echo $SHELL
SHELL是环境变量(所有操作定义环境的变量,每个用户的操作环境不一样),$是调用变量
退出的时候用exit
否则你输入几遍就进入了,第1次父shell,第2次子shell,第3次孙shell…因为在一个shell中,可以调用其他的shell
输出不同颜色的字
echo -e "\033[颜色 字符串 \033[0m"
echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
创建第一个shell脚本
第1行:#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
文件引入
俩种方式:
1、使用.空格 要引入的绝对路径(上图4行)
2、source 要引入的绝对路径(上图5行)
执行方式
俩种方式:
1、使用相对路径 ./文件名
相对路径之所以能执行,是因为/etc/passwd中最后一个字段,所使用的bash,和你#!后面声明的bash解释器一致
2、使用/bin/bash 文件名
输出/输入重定向
1、执行的命令 > 要保存到哪个文件,写绝对路径 //覆盖的方式
2、执行的命令 >> 要保存到哪个文件,写绝对路径 //追加的方式
3、命令<file输出重定向 //输入重定向
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息
demo1:将一个文件清空
echo > test.txt //echo一个空(空格)给文件,是将该文件清空
demo2:故意制造错误(输入错误的命令)
ech ‘aaa’ 2 > /dev/null //将报错信息 导入到 /dev/null中
ech ‘bbb’ > /dev/null 2>&1 //同上
demo3:统计该文件中的行数
shell变量
1、变量的赋值:变量名=值 注意:等号倆边不能有空格
2、变量的访问(在脚本中):先用{}声明变量,再用$调用
echo $username 或者 echo ${username}123
3、单引 和 双引:单引原样输出,双引解析变量
4、字符串拼接:不用点或+拼接,什么都不用加。
username=‘liudehua’
password=‘123456’
echo u s e r n a m e username usernamepassword
5、获取字符串长度:变量前加#
echo ${#username}
6、字符串截取:变量后,用冒号分割2参数
echo ${username:1:3}
shell运算符
1、基本运算符
不支持 直接 + - * /
但是有个命令可以解决 expr 计算的
echo expr $1 + $2
#脚本中的加法计算
注意:不加反引号,就被当成字符串,加上反引会按正常命令执行
2、表达式运算符
== != -eq -ne -gt -lt -ge -le
3、布尔运算符
! -o -a
取反 或 且
4、逻辑运算符
情况1:在脚本中使用 || && [[ 条件一 && 条件二 ]]
情况2:在命令行中用(也一样,)
5、判断文件运算符
-d 判断是否是目录;
[[ -d $1 ]] || mkdir $1 #如果该目录不存在,则创建
-f 判断是否是文件;
-e 判断文件或目录是否存在;
shell数组
1、定义数组:变量名=(元素1 元素2); //元素用()括起来,以空格为分隔符
username=(‘liudehua’ ‘zhangxueyou’ ‘liming’)
username[3]=‘guofucheng’ //以索引的方式添加元素
2、读取数组:先{}声明变量,用$调用,取下标
echo ${username[2]} //打印出liming
echo ${username[*]} //*打印出数组中的所有元素
echo ${username[@]} //@同上
3、计算数组中的元素:变量名前加#
echo ${#username[*]}
shell传值
在执行脚本的时候传实参:./文件名 参数1 参数2 参数3 (每个参数中间用空格)
在脚本中通过形参接收:$1 $2 $3 (它按顺序接收,所以变量名叫啥都行,)
$# | 传递到脚本的参数个数 |
---|---|
$$ | 脚本运行的当前进程ID号 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
shell流程控制
1、if、elseif、else
注意:不用加分号;表达式中2空格;表达式前1个空格;
一个[ ]表达式中解析的是布尔运算符;2个[[ ]]表达式 中才能使用逻辑运算符
#!/bin/bash
score=$1 #接收参数
if [ $score -lt 60 ] #条件表达式[]中 左右要各加一个空格;表达式前面也要有个空格
then
echo '不及格'
#elif [ $score -gt 60 -a $score -lt 80 ] #elseif、大于60并且小于80、布尔运算符-a等于and
elif [[ $score -gt 60 && $score -lt 80 ]] #逻辑运算符&&
then
echo '优秀'
else
echo 'very good!!'
fi
#如果接收到的参数 等于 888,就输出哈哈哈
[[ $1 -eq 888 ]] && echo '哈哈哈'; #简化写法
2、for循环
在脚本中使用
当做命令使用:每行以分号结束
for dir in ls /home/*;do [[ -d $dir ]] && echo $dir;done //先查看(获取);在判断;最后输出/home目录下的所有目录
如需删除目录,用rm -rf 将echo 替换掉
3、while循环
4、case
#!/bin/bash
username=$1 #接收参数
case $username in
xigua)
echo '唔系 西瓜'
;; #结束 相当于break
cgua)
echo '唔系 C瓜'
;;
*) # *和default是一个意思
echo '雷猴 请问找哪位~'
;;
esac
shell函数
定义函数,2种形式:
1、使用function声明
2、不使用function声明,匿名函数
#!/bin/bash
#第1种
function leiHou(){
echo '使用function声明'
}
#第2种
zhongYi(){
echo '匿名函数'
}
#调用函数,不用加(),也不用拿$
#shell是面向过程,只能先定义,后调用
#相同函数名,调用时,后面的会覆盖前面的
leiHou
zhongYi