shell学习笔记-实战:创建、运行与变量操作
shell - bash
- 一、什么是shell?常见的有哪些?
- 二、如何查看当前使用的shell?
- 三、创建并运行第一个bash脚本
- 1. 创建并打开一个bash脚本文件
- 2. 写入shebang(释伴)
- 3. 添加可执行权限
- 4. 执行脚本
- 四、掌握bash脚本核心语法
- 1.说明
- 2.注释
- 3.变量
- 变量基础
- 字符串变量
- 特殊变量
- 数组
一、什么是shell?常见的有哪些?
我们总是打开终端,去输入Linux命令操作。但是这些命令Linux内核真的能读懂吗?
答案是不能!操作系统看上去像是"听懂了我们的话",又是如何做到的? 最关键的人物就是shell, shell是建立在操作系统内核上的一个应用程序,在用户和内核之间充当翻译官。它的工作是接收用户输入的命令,解释它然后让操作系统去执行,最后把结果返回给用户。
不同的操作系统,写了不同的shell应用程序,看看shell有哪几种?
shell名称 | 解释 |
---|---|
(sh) 全称Bourne Shell | 老祖宗,Unix上最经典的shell之一 |
(Bash)全称Bourne-Again Shell | sh的增强版替代品,在大多数Linux发行版里都是默认shell |
(Ksh)全称KornShell | 在商业Unix上流行 |
(Zsh)全称Z shell | 现代首选,Bash的超集,现在是 macOS 的默认 Shell |
… | … |
更多的shell就不在这里解释了。
如果你学过Linux,那么对SSH一定不陌生吧。这里想对它做一下介绍,SSH是Secure shell的缩写,但要注意它不是一个shell。bash才是真正和你交互的那个人,SSH只是负责确保我们的对话不被监听。SSH为我们创建了一个安全的登录通道,就像一个空洞的加密管子,两头可以传输数据,不负责解析你的ls
或cd
命令,这些是shell(比如bash)的功能。
secure shell的命名体现了它的历史使命和首要应用:安全的获取远程shell.
二、如何查看当前使用的shell?
- 方法一:输入
echo $SHELL
,查看用户当前默认的shell
需要注意$
符号后面的SHELL一定要大写,否则没有输出
- 方法二:输入
echo $0
, 查看正在运行的shell
- 方法三:输入
ps -p $$
,查看正在运行的shell,ps是查看进程相关的命令
提供了查看默认shell,和查看当前正在运行shell的命令,是因为使用shell是可以更改。
三、创建并运行第一个bash脚本
当别人说“Shell 脚本”时,通常指的是用 Bash 语法写的脚本,但严格来说,它也可能是为其他 Shell 写的。
bash脚本文件,后缀为.sh
1. 创建并打开一个bash脚本文件
//创建,然后打开
# touch test.sh
# vim test.sh
2. 写入shebang(释伴)
//写入释伴
#!/bin/bash
#!
连在一起,叫做shebang。它位于 shell 脚本文件的第一行,用来声明这个脚本文件需要由/bin/bash
这个解释器来执行。
python也是一个解释型语言,在python脚本文件里,你也可以写入#!/usr/bin/python
,来声明该python脚本文件需要由/usr/bin/python
这个解释器来执行。
//写入其他内容
echo "Hello, World!"
3. 添加可执行权限
touch文件时,如果默认权限不带执行权限,就需要用chmod加上
//添加执行权限
chmod +x test.sh
4. 执行脚本
用./
带上脚本文件路径+文件名,就可以执行了。
四、掌握bash脚本核心语法
1.说明
博主本身是有一些Linux命令操作基础和C/C++语言基础的,这篇博客也是自己用来做笔记的,所以有些在Linux上常见的语法和很基础的概念这里就不作解释。
2.注释
单行注释使用#
多行注释方法一:每行都用#
多行注释方法二:使用Here Document
使用形式:
:<<'comment'
注释内容
comment
需要注意在:<<‘comment’
行和comment
行不能用bash的注释#
代码解释:
:
bash里面的空命令,什么都不做,永远返回成功
<< 'comment'
这是一个Here Document的开始,它把后面的逐行内容作为输入,直到遇到单行的分界符comment
最后一行的comment
表示Here Document的结束
多行注释方法三:转为函数,没有地方去调用该函数
3.变量
变量基础
- bash脚本定义变量初始化时,等号两边不要有空格
- 引用变量,用
${ }
,{}
是可选的,为了帮助bash解释器识别变量的边界。如果${}
后面没有其他紧接着的字符,就可以去掉{}
name="yangdongyan" # 定义变量,等号两边不能有空格
echo "Hello, ${name}" # 使用变量
echo "Hello, $name" # {}可去掉
- bash脚本变量可以多次赋值,这个时候不要用
$
- 可以用
readonly xxx
修饰bash脚本变量xxx,将它变为只读变量,不可修改 - 使用
unset xxx
删除bash脚本变量xxx
字符串变量
当我们直接这样定义变量,通常被视为字符串类型变量
name='yangdongyan'
name="yangdongyan"
字符串可以用单引号' '
,也可以用双引号" "
。
- 单引号内的所有字符都会失去它的特殊含义,被原封不动地,字面地解释为普通字符。
- 单引号内不能嵌套单引号,否则会出现下面的情况
name='yangdongyan'okaaa'
echo ${name}
3.字符串可以拼接,用'字符串1''字符2'
的方式可以将多个字符串拼接起来。
可能会纳闷,拼接字符串这里面好像就是嵌套了单引号。
测了一下,单引号字符串是奇数个的时候,会被认为是嵌套了单引号;如果是偶数个的话,会自动配对,认为是字符串拼接
可以看到这种情况也被视为字符串拼接。aaaa
会被认为没有被任何引号包裹着:未引用的字符串。也会和前后进行拼接
-
可以用
${# }
获取字符串的长度
-
可以用
${X:i:n}
提取字串,从字符串变量i位置提取n个字符,字符串i从0算起。注意冒号两边不能有空格,否则执行时会出现bad substitution
的字段。
特殊变量
脚本参数
$0
脚本名
$1
、 $2
、 $3
…9
第一到第9个脚本参数
$#
参数个数
$@
所有参数,每个作为独立单词
$*
所有参数,合并为一个字符串
$?
状态码上一条命令的退出状态
$$
当前shell的PID
$!
最后一个后台进程的PID
可以看到第一次$*
的时候,和$@
的打印似乎都是一样的,最后一次$*
的时候打印出来的又是其他形式的。
这是因为$*
先分割,再拼接的时候,用变量$IFS
来作为分隔符,后面我们修改$IFS
就可以看到区别了。
数组
定义形式: array=("value1" "value2" "value3".....)
value1是值1,value2是值2,字符串和字符串之间要用空格分割开来
赋值:array[i]="new_value"
,i为数组array的第i个元素位置,i从0开始算起。
访问方式:${array[i]}
访问第i个元素,i从0算起
访问所有元素:${array[@]}
或者${array[*]}
获取数组元素的个数:${#array[@]}
或者${#array[*]}
获取某个元素的长度:${#array[i]}
,i为元素下标,从0算起