shell 简介
Shell 提供给用户一个基于文本的输入输出接口,作为用户和内核之间的桥梁。它之所以被称作shell是因为它隐藏了操作系统低层的细节。
目前在 Linux 操作系统中最常用的 shell 就是 Bourne-Again Shell
(BASH
),除了 bash 以外,还有其他的 shell 例如: Tcsh/Csh, Ksh, Zsh, Fish shell
shell 命令与 shell 脚本
在 Linux 的哲学当中,一条命令只负责做好一件事情
Shell 脚本就是一种编程脚本,用于自动化执行一系列命令和任务,并且可以被其他脚本复用
- Shell 脚本一般后缀为
.sh
,使用 Vim 或 Emacs 识别到后缀名后可以提供语法高亮,补全,检查等功能 - 执行 Shell 脚本的两种方式
sh shell_script.sh
./shell_script.sh
Shell 脚本编程基础
Linux 文本流
当一个进程被执行时,会打开三个文本流的端口:
- 标准输入(stdin):从输入设备(通常是键盘)读取数据。文件描述符为
0
- 标准输出(stdout):将数据输出到显示设备(通常是屏幕)。文件描述符为
1
- 标准错误(stderr):输出错误信息,通常也是显示设备。文件描述符为
2
重定向
顾名思义,就是将标准的文本流重定向到其他的文件或者设备中。
- 将标准输出重定向
command > output.txt
- 将标准错误重定向
command 2> error.txt
- 同时重定向标准错误和标准输出
command > output.txt 2>&1
以上方式会以覆盖的方式进行,如果想要添加到文件末尾,我们可以使用>>
- 将标准输入重定向
command < inputfile
- 内联输入重定向
command << END
内联输入重定向可以将实时键入文本作为输入,以 END 作为结束,例如
$ cat << END
> hello
> world
> !
> END
hello
world
!
管道(pipe)
管道是一种进程间通信的方法,当我们使用管道将两个进程连接时候,就可以将前一个程序的标准输出作为后一个程序的标准输入,就像水管控制水流一样,管道控制着文本流
command1 | command2 | command3
变量
变量定义
foo='bar'
$ echo $foo
bar
$ echo foo
foo
- Shell 中的变量通常被视为字符串类型的
- 变量名和等号之间不能有空格
- 通过一个变量我们可以访问一块内存,变量名是这块内存的标签
- 通过使用
$var_name
访问变量,或者我们一般加上花括号${var_name}
- 关于命名规则,同其他编程语言类似
变量分类
- 环境变量:这些是由操作系统或用户设置的特殊变量,用于配置 Shell 的行为和影响其执行环境。
例如,PATH 变量包含了操作系统搜索可执行文件的路径:
$ echo $PATH
/mingw64/bin:/usr/bin:/c/Users/marklee/bin
我们可以使用 printenv
查看所有环境变量
- 特殊变量: 有一些特殊变量在 Shell 中具有特殊含义,例如
$0
表示脚本的名称,$1
,$2
, 等表示脚本的参数。$#
表示传递给脚本的参数数量,$?
表示上一个命令的退出状态等。 - 全局变量 :作用在整个 shell 会话和 shell 的子进程中
- 局部变脸 :作用在定义的进程和其子进程中
算数扩展
可以用于简单的生疏算术运算
$ echo $[3+2]
5
$ echo $[4/2]
2
$ echo $[0*1314]
0
shell 脚本解释器
Shell 脚本解释器是一种用于执行 Shell 脚本的程序,它读取并解释脚本中的命令,并在操作系统上执行这些命令
Shebang (#!
)
Shell 脚本的第一行通常以 #!
开头,后跟解释器的路径,例如:
#!/bin/bash
这个行被称为 “shebang”,它告诉操作系统使用哪种解释器来执行这个脚本。如果没有指定解释器,系统将默认使用用户当前的 Shell
流程控制
条件判断
- if-then-else
示例
num=10
if [ $num -gt 5 ]; then
echo "num 大于 5"
else
echo "num 小于或等于 5"
fi
- case
day="Monday"
case $day in
"Monday")
echo "今天是星期一"
;;
"Tuesday")
echo "今天是星期二"
;;
*)
echo "不知道今天是星期几"
;;
esac
循环语句
- for
for i in 1 2 3 4 5; do
echo "数字: $i"
done
- while
count=1
while [ $count -le 5 ]; do
echo "计数: $count"
count=$((count + 1))
done
- until
count=1
until [ $count -gt 5 ]; do
echo "计数: $count"
count=$((count + 1))
done