shell的作用
shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
解释执行用户输入的命令或程序等
用户输入一条命令,shell就解释一 条
键盘输入命令,Linux给与响应的方式,称之为交互式
我们日常在linux上敲的命令行,如ls
pwd
等,会先发送给shell解释器进行解释,然后程序执行。
/image-20220803170633157.png)
什么是bash
bash是一个命令处理器,运行在文本窗口中,并能执行用户直接输入的命令
bash还能从文件中读取linux命令,称之为脚本
bash支持通配符、管道、命令替换、条件判断等逻辑控制语句
shell脚本
当命令或者程序语句写在文件中,我们执行文件,读取其中的代码,这个程序文件就称之为shell脚本。shell属于弱类型的语言
在shell脚本里定义多条Linux命令以及循环控制语句,然后将这些Linux命令一次性执行完毕,执行脚本文件的方式称之为,非交互式方式。
Linux中常用.sh
脚本文件,就是俗称的shell脚本。
shell脚本demo实例
在写shell脚本时,第一行要# !/bin/sh
。我们称#!
称为sheang
在Unix系统中,程序会分析shebang 后面的内容,作为解释器的指令,例如:
以#!/bin/sh 开头的文件,程序在执行的时候会调用/bin/sh ,也就是bash解释器
以#!/usr/bin/python 开头的文件,代表指定python解释器去执行
以#!/usr/bin/env 解释器名称,是一种在不同平台上都能正确找到解释器的办法
如果脚本未指定shebang ,脚本执行的时候,默认用当前shell去解释脚本,即
$SHELL
如果shebang指定了可执行的解释器,如
/bin/bash /usr/bin/python
,脚本在执行时,文件名会作为参数传递给解释器。如果
#
指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission denied"
。如果
#
指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。如果
#!
指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。如果你使用
"bash test.sh"
这样的命令来执行脚本,那么#!
这一 行将会被忽略掉,解释器当然是用命令行中显式指定的bash
当我们执行 ls -l /bin/sh
时,我们就发现其实这是个软链接指向bash。
/image-20220803184539554.png)
软硬链接
现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程创建信息的逻辑单元可被多个进程并发使用。
文件:文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,比如创建时间、修改时间、文件大小、属主、归属的用户组、读写权限、数据所在block号等。
inode:在Linux的文件系统中,保存在磁盘分区中的文件,不管是什么类型都会给它分配一个编号,这个编号被称为索引节点编号(inode index)或者inode。inode 是文件元数据的一部分,但其并不包含文件名。在 Linux ,元数据中的 inode 号是文件在一个文件系统中的唯一标识,不同文件系统inode号可以相同。系统或程序通过 inode 号寻找正确的文件数据块,而不是文件名。换句话说,操作系统只认inode号,不认文件名,文件名是方便人类而存在的。
硬链接(Hard Link):在Linux系统中,多个文件名指向同一索引节点(Inode)是正常且允许的。一般这种链接就称为硬链接。
软链接:类似于windows系统中的快捷方式,与硬链接不同,软链接就是一个普通文件,只是数据块内容有点特殊,文件用户数据块中存放的内容是另一文件的路径名的指向,通过这个方式可以快速定位到软连接所指向的源文件实体。软链接可对文件或目录创建。
代码样例
#!/bin/sh
echo "Hello World"
在运行时,我们可以用以下命令
./hello.sh # 需要先用chmod +x hello.sh获取执行权限
/bin/bash ./hello.sh
/bin/sh ./hello.sh
bash的其他常用命令
echo $HISTSIZE # 查询记录多少条历史命令
echo $HISTFILE # 存储在./username/bash_history
history -c # 清除历史命令 -r 恢复历史命令,但是在家目录下的bash_history依然存储
!! # 执行上次命令
shell变量
shell默认变量都为字符串,无需事先定义数据类型
变量引入:
echo {$变量名$}
父子shell:
命令行输入 sh
,再去查看 pstree
/image-20220804105231499.png)
当我们输入 exit
退出,再去查看,会有明显的不一样:
/image-20220804105312480.png)
当我们再 exit
就会退出登录。子父shell变量不共享。这里就牵扯到了shell脚本作用域的问题。
单引号变量不能识别特殊语法,即echo ‘{$变量名$}’ 是无法输出变量名的值
shell脚本作用域
环境变量,也称为全局变量,针对当前shell以及其任意子进程,环境变量也分自定义、内置两种环境变量
局部变量,针对在shell函数或是shell脚本中定义
位置参数变量,用于shell脚本中传递的参数
特殊变量,shell内置的特殊功效变量
- $? (常用在脚本里判断上一次命令是否执行成功)
- 0:成功
- 1-255: 错误码
- $? (常用在脚本里判断上一次命令是否执行成功)
自定义变量
- 变量赋值:varName=value
- 变量引用: ${varName} 、$varName
当我们每次调用bash都会开启一个子shell,不保留当前的shell变量
环境变量设置
环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。
环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件
用户个人配置文件
/.bash_ profile 、/.bashrc 远程登录用户特有文件全局配置文件/etc/profile 、/etc/bashrc ,且系统建议最好创建在/etc/profile.d/ ,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户
检查系统环境变量的命令
set, 输出所有变量,包括全局变量、局部变量
env,只显示全局变量
declare,输出所有的变量,如同set
export, 显示和设置环境变量值
撤销环境变量
- unset 变量名,删除变量或函数。
设置只读变量
- readonly ,只有shell结束,只读变量失效
环境变量文件加载顺序
其他特殊变量
shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量
$0:获取shell脚本文件名,以及脚本路径
$n:获取she11脚本的第n个参数,n在1~9之间,如$1 ,$2, $9,大于9则需要写,${10}, 参数空格隔开
$#:获取执行的she11脚本后面的参数总个数
$*:获取shel1脚本所有参数,不加引号等同于$@作用,加上引号”$*“作用是接收所有参数为单个字符串,”$1 $2..
$@:不加引号,效果同上,加引号,是接收所有参数为独立字符串,如”$1” “$2” “$3” …,空格保留
内置shell命令
内置命令:在系统启动时就加载入内存,常驻内存,执行效率更高,但是占用资源,不需要开子进程
外置命令:用户需要从硬盘中读取程序文件,再读入内存加载
echo # -n 不换行输出 -e 解析字符串中的特殊符号 \b 退格 \t 制表符(四个空格)
printf # 打印命令
eval # 执行多个命令
exec # 不创建子进程,执行完自动exit
export
read
shift
shell子串的其他用法
/image-20220805090058403.png)
time命令,统计命令执行时长。
for循环
for number in {1. .100}
do
echo $number
done
写在一行的方法
for num in {1. .100};do echo $num; done