脚本文件第一行要求使用shebang(#!)符号指定一个脚本的解释器,如#! /bin/bash、#! /bin/sh、#!/usr/bin/env python等
<<符号后面的关键词可以是任意字符串,但前面使用什么关键词,结束注释时必须使用相同的关键词。如果从<<ABC开始注释,则结束注释信息时也必须使用ABC(字母区分大小写)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cupkwE7P-1660468289831)(C:\Users\liwei\AppData\Roaming\Typora\typora-user-images\image-20220814152816041.png)]
1)脚本文件自身没有可执行权限
如果暂时还没有给脚本文件可执行的权限,那么默认脚本是无法直接执行的,但bash或sh这样的解释器,可以将脚本文件作为参数(读取脚本文件中的内容)来执行脚本文件。
2)脚本文件具有可执行权限
脚本文件一旦有了执行权限,就可以使用绝对路径或相对路径执行了。
3)开启子进程执行的方式 bash 绝对路径、相对路径执行 默认开启
4)不开启子进程的执行方式
使用source或.(点)命令来执行脚本文件。
echo 、printf
标准输出的文件描述符为1,标准错误输出的文件描述符为2。而标准输入的文件描述符则为0。
如果希望改变输出信息的方向,可以使用>或>>符号将输出信息重定向到文件中。使用1>或1>>可以将标准输出信息重定向到文件(1可以忽略不写,默认值就是1),也可以使用2>或2>>将错误的输出信息重定向到文件。这里使用>符号将输出信息重定向到文件,如果文件不存在,则系统会自动创建该文件,如果文件已经存在,则系统会将该文件的所有内容覆盖(原有数据会丢失!)。而使用>>符号将输出信息重定向到文件,如果文件不存在,则系统会自动创建该文件,如果文件已经存在,则系统会将输出的信息追加到该文件原有信息的末尾。
Linux系统中有一个特殊的设备/dev/null,这是一个黑洞。无论往该文件中写入多少数据,都会被系统吞噬、丢弃。
当需要读取变量值时,需要在变量名前添加一个美元符号“$”;而当变量名与其他非变量名的字符混在一起时,需要使用{}分隔。
hello = 3 # 错误 等会两边不可以有空格
hello1=3 #正确
echo $hello1 #调用变量提前变量的值
常见的系统预设变量
| 变量名 | 描述 |
|---|---|
| UID | 当前账户uid |
| USER | 当前账户名 |
| HOME | home路径 |
| LANG | 当前系统语言 |
| PATH | 命令所搜路径 |
| PWD | 当前路径 |
| RANDOM | 随机数 |
| $0 | 当前命令的名称 |
| $n | 第n个位置参数 |
| $? | 上一个命令运行的状态,0成功 1 失败 |
| $# | 参数个数 |
| $* | 所有参数 |
| $$ | 返回当前进程id |
| $! | 最后一个进程id |
在Shell中可以使用多种方式进行条件判断,如
1、[[表达式]]
2、[表达式]或
3、test表达式。
使用条件表达式可以测试文件属性,进行字符或数字的比较。需要注意的是,不管使用哪种方式进行条件判断,系统默认都不会有任何输出结果,可以通过echo $?命令,查看上一条命令的退出状态码,或者使用&&和||操作符结合其他命令进行结果的输出操作。
如果需要在一行代码中输入多条命令,在Shell中可以使用;(分号)、&&(与)、||(或)这三个符号将多个命令分隔。其中;(分号)是按顺序执行命令,分号前后的命令可以没有任何逻辑关系。例如,输入“A命令;B命令”,系统会先执行A命令,不管A命令执行结果如何,都会执行B命令。整个命令的退出码以最后一条命令为准,B命令如果执行成功则退出码为0, B命令如果执行失败则退出码为非0。而使用&&(与)符号分隔多条命令时,仅当前一条命令执行成功后,才会执行&&后面的命令。例如,输入“A命令&&B命令”,系统会先执行A命令,如果A命令执行成功则执行B命令,如果A命令执行失败则不执行B命令。而整行命令的退出码取决于两条命令是否同时执行成功,如果A命令执行成功并且B命令执行也成功,则整行命令的退出码为0,而A命令或B命令中的任何一条命令执行失败,则整行命令的退出码为非0。如果使用||(或)符号分隔多条命令,仅当前一条命令不执行或执行失败后才执行后一条命令。
;分号顺序执行
&& 成功才继续执行
|| 不执行或失败才继续执行
test a == a # 判断字符串是否相等 测试代码 等会前后一定要有空格 ; 赋值才没空格
echo $?
[$USER == root]
echo $?
[[$USER == root]] && echo y || echo n
[$USER != root] && echo y || echo n
整数的比较运算符
| 符号 | 含义 |
|---|---|
| -eq | 等于 |
| -ne | 不等于 |
| -gt | 大于 |
| -ge | 大于等于 |
| -lt | 小于 |
| -le | 小于等于 |
文件属性判断操作符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O6fQlCwN-1660468289839)(C:\Users\liwei\AppData\Roaming\Typora\typora-user-images\image-20220814160047841.png)]
# 判断文件是否存在
[-e file.txt] && echo y || echo n
# 判断目录是否存在
[-e /home] && echo y || echo n
对于简单的条件判断,结合&&和||就可以完成大量的脚本。但是当脚本越写越复杂、功能越写越完善时,简单的&&和||就不足以满足需求了。此时,选择使用if语句结合各种判断条件,功能会更加完善和强大。在Shell脚本中if语句有三种格式,分别是单分支if语句、双分支if语句和多分支if语句。下面是单分支if语句的语法格式。
if 条件语句
then
命令序列
fi
if和then可以写同一行用 分号隔开
if 条件语句;then
命令序列
fi
#!/bin/bash
read -p "请输入用户名:" username
read -s -p "请输入密码" password
if [! -z "$username"];then
useradd "$username"
fi
if [! -z "$password"];then
echo "$password" |passwd --stdin "$username"
fi
#!/bin/bash
read -p "user" username
read -s -p "password" password
if [[ ! -z "$username" && ! -z "$password" ]];then #注意此处 要用双[[]] ,注意空格
useradd "$username"
echo "$password" | passwd --stdin "$username"
fi
与单分支if语句的格式一样,then和if可以写在同一行,也可以分开写在不同行。甚至在else和命令序列1中间添加分号将其写在同一行,但很少有人这样写,这将导致代码的可读性非常差。
if 条件测试 ;then
命令序列1
else
命令序列2
fi
#!/bin/bash
if [ ! -z $1 ];then
echo "参数不为空"
else
echo "参数为空"
fi
if的双分支语法结构仅可以对事务的正确与错误两种情况做出回应,而现实问题往往更复杂,比如数字的大于、小于、等于判断。多分支if语句支持else if(简写elif)子句,可以实现在else中内嵌if的功能。在多分支if语句中elif可以出现多次,实现多次测试判断的效果。首先,来看看多分支if语句的语法格式。
if 条件测试 ;then
命令序列1
elif
命令序列2
elif
命令序列3
…
else
命令序列n
fi
#!/bin/bash
read -p "请输入分数" score
if [[ $score -gt 90 ]];then
echo "优秀"
elif [[ $score -gt 80 ]];then
echo "良好"
elif [[ $score -gt 70 ]];then
echo "中等"
elif [[ $score -ge 60 ]];then
echo "及格"
else
echo "不及格"
fi
case语句语法格式
case word in
模式1 )
命令1;;
模式2)
命令2;;
…
*)
命令n;;
esac
case支持多个条件匹配
case word in
模式1|模式2|模式3)
命令1 ;;
模式4|模式5|模式6)
命令2;;
*)
命令n;;
esac
#!/bin/bash
read -p "输入一个a-f 的字母" key
case $key in
a)
echo "i am a";;
b)
echo "i am b";;
c|d|e|f)
echo "i am in cdef";;
*)
echo "out of range";;
esac
#!/bin/bash
if [[ $# -lt 1 ]];then
echo "请输入参数执行脚本时"
exit 1
fi
zifu=$1
case $zifu in
[a-z])
echo "小写字母";;
[A-Z])
echo "大写字母";;
[0-9])
echo "数字";;
*)
echo "OTHERS"
esac
1.for循环
2.嵌套循环
3.while循环
4.untile和select循环
5.终端与推出控制