shell脚本(一)


shell的作用

shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

  1. 解释执行用户输入的命令或程序等

  2. 用户输入一条命令,shell就解释一 条

  3. 键盘输入命令,Linux给与响应的方式,称之为交互式

我们日常在linux上敲的命令行,如ls pwd等,会先发送给shell解释器进行解释,然后程序执行。

什么是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 解释器名称,是一种在不同平台上都能正确找到解释器的办法

  1. 如果脚本未指定shebang ,脚本执行的时候,默认用当前shell去解释脚本,即$SHELL​

  2. 如果shebang指定了可执行的解释器,如/bin/bash /usr/bin/python,脚本在执行时,文件名会作为参数传递给解释器。

  3. 如果 # 指定的解释程序没有可执行权限,则会报错 “bad interpreter: Permission denied"

  4. 如果 # 指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。

  5. 如果 #! 指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。

  6. 如果你使用 "bash test.sh" 这样的命令来执行脚本,那么 #! 这一 行将会被忽略掉,解释器当然是用命令行中显式指定的bash

当我们执行 ls -l /bin/sh 时,我们就发现其实这是个软链接指向bash。

软硬链接

现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程创建信息的逻辑单元可被多个进程并发使用。

文件:文件都有文件名与数据,这在 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

当我们输入 exit 退出,再去查看,会有明显的不一样:

当我们再 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子串的其他用法

time命令,统计命令执行时长。

for循环

for number in {1. .100}
do
echo $number
done

写在一行的方法

for num in {1. .100};do echo $num; done

文章作者: 小小星仔
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小星仔 !
评论
  目录