一、shell是什么?
1. 1 shell 是一种脚本语言
脚本语言的本质是一个文件,文件里面存放的是特点格式的指令,系统可以使用脚本解析器翻译或者解析指令,并且执行(它不需要编译)
shell 即是应用程序,又是一种脚本语言(应用程序、解析、脚本语言)
shell命令解析器:
系统提供shell命令解析器:sh 、ash 、bash等等
查看自己linux系统的默认解析:echo $SHELL 或者 grep ^root /etc/passwd
echo $SHELL
grep ^root /etc/passwd
1. 2 shell的结构
由底层到应用层如下:
硬件 ——> kernel ——> shell -> 脚本语言
1. 3 用户跟内核通信
用户使用文字或者图形界面操作系统(用户)
接受来自用户的命令与内核进行沟通(使用者界面 shell ,KDE,application)
真正控制硬件进行工作、进程管理,存储管理等(内核 kernel)
CPU 、 内存、显卡、显示器、硬盘等(硬件hardware)
shell脚本是一种脚本语言,我们只需要任意文本编译器,按照编写相应的应用程序,增加可执行权限,既可以安装shell命令的环境下运行
1. 4 调用形式
打开终端时系统自动调用:、etc/profile或者/etc/bashrc
手动调用:
source /etc/profile
source /etc/bashrc
source /etc/bash.bashrc
source /etc/profile.d/bash_completion.sh
source /etc/bash_completion
source /etc/bash_completion.d/git-prompt.sh
source /etc/bash_completion.d/git-completion.bash
source /etc/bash_completion.d/git-completion.zsh
/etc/profile
此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里
设置开机自启的程序,一般也在这里设置
~/.bashrc
用户自己的家用目录中的.bashrc
登录时会自动调用,打开任意终端时也会自动调用
这个文件一般设置与个人有关的环境变量,比如交叉编译器的路径等等
用户手动调用:用户实现的脚本
二、shell 操作
2.1 语法
2.1.1 定义已开头:
#!/bin/bash
!:表示这个脚本文件需要使用/bin/bash来执行
单个“#”号:表示注释,不会被执行
2.1.2 追加执行权限:
chmod +X day01.sh
2.1.3 执行:
./day01.sh
2.1.4 三种执行方式:
2.1.4.1.直接执行:
./day01.sh
2.1.4.2.执行并查看执行结果:
bash day01.sh
2.1.4.3.执行并查看执行结果:
sh day01.sh
./xxx.sh:先按照文件中#!指定的解析器解析,如果没有,才会使用系统默认的解析器
bash XXX.sh:指明先按照bash解析,如果没有,才会使用系统默认的解析器
2.2 变量
2.2.1 定义变量:
变量名=值
例如:
name=zhangsan
2.2.2 引用变量:
${变量名}
例如:
echo ${name}
echo "$name"
echo $name
2.2.3 unset:
删除变量
例如:
unset name
echo ${name}
2.2.4 示例
name=zhangsan
echo "name:$name"
echo "请输入姓名:"
read name
echo "name:$name"
echo "请输入年龄:"
read age
echo "age:$age"
if [ $age -gt 18 ];then
echo "你已经成年了"
else
echo "你还未成年"
fi
在一行上显示和添加提示需要加上-p:
# 在一行上显示和添加提示需要加上-p
read -p "请输入年龄:" age
if [ $age -gt 18 ];then
echo "你已经成年了"
else
echo "你还未成年"
fi
读取多个值:
read -p "请输入姓名:" name age
echo "name:$name"
echo "age:$age"
if [ $age -gt 18 ];then
echo "你已经成年了"
else
echo "你还未成年"
fi
只读变量:(不可修改)
readonly name="zhangsan"
echo $name
name="zhangsan1"
echo $name
name="lisi"
echo $name
查看环境变量:
echo $PATH
env
2.3 source命令用法:
等号:
2.4 预设变量:
例如:
echo "脚本名称:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "第三个参数:$3"
echo "第四个参数:$4"
echo "第五个参数:$5"
echo "第六个参数:$6"
echo "第七个参数:$7"
echo "第八个参数:$8"
echo "第九个参数:$9"
echo "第十个参数:$10"
echo "参数个数:$#"
echo "所有参数:$*"
echo "所有参数:$@"
2.5 "" '' `` \ () {}的特殊用法:
name="cdy"
echo "hello $name"
echo 'hello $name'
echo `echo $name`
echo $(echo who am i)
echo `echo "hello 1 \n hello"`
echo `echo -e "hello 1 \n hello"`
age=18
(
#子shell完成不会影响父shell
echo $age
age=19
echo "里面age: $age"
echo "里面:$((age+1))"
)
echo "外面age: $age"
2.6 {}由当前的shell执行:
age=18
{
echo $age
age=19
echo "里面age: $age"
echo "里面:$((age+1))"
}
echo "外面age: $age"
2.7 变量扩展:
2.8 字符串的操作:
2.9 测试[ ]用法:
if [ -d /home/cdy ]
then
echo "目录存在"
else
echo "目录不存在"
fi
if [ -f /etc/passwd ]
then
echo "文件存在"
else
echo "文件不存在"
fi
if [ -x /etc/passwd ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -r /etc/passwd ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w /etc/passwd ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -s /etc/passwd ]
then
echo "文件不为空"
else
echo "文件为空"
fi
2.10 test命令用法:
if test -f /etc/passwd
then
echo "文件存在"
else
echo "文件不存在"
fi
if test -d /etc
then
echo "目录存在"
else
echo "目录不存在"
fi
if test -r /etc/passwd
then
echo "文件可读"
else
echo "文件不可读"
fi
if test -w /etc/passwd
then
echo "文件可写"
else
echo "文件不可写"
fi
if test -x /etc/passwd
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if test -s /etc/passwd
then
echo "文件不为空"
else
echo "文件为空"
fi
if test -e /etc/passwd
then
echo "文件存在"
else
echo "文件不存在"
fi
if test -d /etc/passwd
then
echo "文件是目录"
else
echo "文件不是目录"
fi
2.11 字符串测试:
if test "abc" = "abc"
then
echo "字符串相等"
else
echo "字符串不相等"
fi
if test "abc" != "abc"
then
echo "字符串不相等"
else
echo "字符串相等"
fi
name="cdy"
test -z $name
echo $?
read -p "请输入用户名:" name
[ -z $name ]
echo "1:$?"
if [ -z $name ]
then
echo "用户名不能为空"
else
echo "用户名不为空"
fi
2.12 数值测试:
2.13 语句测试:
2.14 控制语句:
2.15 case:
2.16 for循环语句:
2.17 while语法:
2.18 until语法语法:
2.19 continue 和 break:
2.20 函数:
三、总结
在Shell脚本中,单括号 `[ ]` 和双括号 `[[ ]]` 都用于条件测试,但它们之间存在一些重要的区别:
3.1 单括号 [ ]:
这是POSIX标准的一部分,所有Unix-like系统兼容。
在 `[ ]` 中进行条件测试时,需要使用到 `test` 命令,即使在 `[ ... ]` 中并不显式写出 `test` 关键字。
字符串比较时,不支持模式匹配或者正则表达式。
对于变量内容,会进行词分割(word splitting)和文件名扩展(globbing)。
当条件失败时,返回非零退出状态码。
示例:
a=2
b=2
# # 单括号
if [ "$a" = "$b" ]; then
echo "a和b相等"
fi
3.2 双括号 [[ ]]:
Bash shell特有的扩展条件构造,提供了比单括号更多的功能和更友好的语法。
- 不是所有shell都支持双括号,但在Bash和其他一些现代shell中可用。
- 双括号内无需使用 `test` 命令。
- 支持模式匹配(`=~`)操作符,可以配合正则表达式进行字符串比较。
- 不会进行词分割或文件名扩展。
- 内部的逻辑可以更灵活,例如支持逻辑运算符 `&&` 和 `||` 直接连接条件。
- 当条件失败时同样返回非零退出状态码,但错误检查和解析通常更宽容。
额外的区别还包括:
- 双括号中可以直接使用 `!=`、`>`、`>=`、`<`、`<=` 等比较运算符而不必像
- 单括号那样加上 `-ne`、`-gt` 等前缀。
- 双括号支持字符串长度比较,如 `[[ -z $var ]]`;
- 判断变量是否为空,`[[ ${#var} -gt 5 ]]` 判断变量长度是否大于5。
- 双括号中的 `==` 和 `!=` 在做字符串比较时,两边不需要转义空格或其他特殊字符(除非这些字符在正则表达式模式匹配中具有特殊意义)。
3.3 $()和$(())的区别 :