sh脚本笔记

发布于:2024-06-26 ⋅ 阅读:(17) ⋅ 点赞:(0)

Shebang

计算机程序中,shebang指的是出现在文本文件的第一行前两个字符#!
在Unix系统中,程序会分析shebang后面的内容,作为解释器的指令,例如

  • #!/bin/sh开头的文件,程序在执行的时候会调用/bin/sh,也就是bash解释器
  • #!/user/bin/python开头的文件,代表指定python解释器去执行
  • #!/user/bin/env开头的文件,是一种在不同平台上都能正确找到解释器的办法

注意事项:

  • 如果脚本未指定shebang,脚本执行的时候,默认用当前shell去解释脚本,即$SHELL
  • 如果shebang指定了可执行的解释器,如/bin/bash/usr/bin/python,脚本在执行时,文件名会作为参数传递给解释器
  • 如果#!指定的解释程序没有可执行权限,则会报错"bad interpreter:Permission denied"
  • 如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。
  • 如果#!指定的解释程序不存在,那么会报错"bad interpreter:No such file or directory"
  • #!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。
  • 如果你使用"bash test.sh"这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显示指定的bash。

shell变量

  • 变量定义与赋值,注意变量与值之间不得有空格
name="超哥"

变量名
变量类型,bash默认把所有变量都认为是字符串

bash变量是弱类型,无需事先声明类型,是将声明和赋值同时进行
  • 变量替换/引用
# name="超哥"
# echo ${name}
超哥
# echo $name  # 可以省略花括号
超哥
  • 变量名规则
    • 名称定义要做到见名知意,切按照规则来,切不得引用保留关键字(help检查保留字)
    • 只能包含数字、字母、下划线
    • 不能以数字开头
    • 不能用标点符号
    • 变量名严格区分大小写
  • 变量的作用域
    • 本地变量,只针对当前的shell进程
    • 环境变量,也称为全局变量,针对当前shell以及其任意子进程,环境变量也分自定义内置两种环境变量
    • 局部变量,针对在shell函数或是shell脚本中定义
  • 位置参数变量:用于shell脚本中传递的参数
  • 特殊变量:shell内置的特殊功效变量
    • $?
      • 0:成功
      • 1-255:错误码
  • 自定义变量
    • 变量赋值:varName=value
    • 变量引用:${varName}$varNam
      • 双引号,变量名会替换为变量值
      • 单引号,识别为普通字符串

环境变量设置

环境变量一般指的是export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。
shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。
环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件

  • 用户个人配置文件~/.bash_profile~/.bashrc远程登录用户特有文件
  • 全局配置文件/etc/profile/etc/bashrc,且系统建议最好创建在/etc/profile.d,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户。

检查系统环境变量的命令

  • set,输出所有变量,包括全局变量、局部变量
  • env,只显示全局变量
  • declare,输出所有的变量,如同set
  • export,显示和设置环境变量值

撤销环境变量

  • unset 变量名,删除变量或函数

设置只读变量

  • readonly,只有shell结束,只读变量失效

系统保留环境变量关键字

bash内嵌了诸多环境变量,用于定义bash的工作环境

# export | awk -F '[ :=]' 'print $3'

bash多命令执行

# ls /data;cd /tmp/;cd /home;cd /data

shell特殊参数变量

取出变量值

  • 单引号,所见即所得,强引用
  • 双引号,输出引号里所有内容,识别特殊符号,弱引用
  • 无引号,连续的符号可以不加引号,有空格则有歧义,最好使用双引号
  • 反引号,引用命令执行结果,等于$()用法

特殊变量

shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量

$0   获取shell脚本文件名,以及脚本路径
$n   获取shell脚本的第n个参数,n在1~9之间,如$1$2$9,大于9则需要写,${10},参数空格隔开
$#   获取执行的shell脚本后面的参数总个数
$*   获取shell脚本所有参数,不加引号等同于$@作用,加上引号"$*"作用是接收所有参数为单个字符串,"$1 $2 ..."
$@   不加引号,效果同上,加引号,是接收所有参数为独立字符串,如"$1" "$2" "$3" ...,空格保留

$*和$@ 的区别

$*$@都表示传递给函数或脚本的所有参数

当$*$@不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。

但是当它们被双引号" "包含时,就会有区别了:
"$*"会将所有的参数整体上看做一份数据,而不是把每个参数都看做一份数据。
"$@"仍然将每个参数都看作一份数据,彼此之间是独立的。

比如传递了5个参数,那么对于"$*"来说,这5个参数会合并到一起形成一份数据,它们之间是无法分隔的;而对于"$@"来说,这5个参数是互相独立的,它们是5份数据。

如果使用echo直接输出$*$@做对比,是看不出区别的;但如果使用for循环来逐个输出数据,立即就能看出区别来。

shell特殊状态变量

$?   上一次命令执行状态返回值,0正确,非0失败
$$   当前shell脚本的进程号
$!   上一次后台进程的PID
$_   再次之前执行的命令,最后一个参数

查找方式man bash
		搜索Special Parmeters

bash一些基础的内置命令

echo

-n   不换行输出
-e   解析字符串中的特殊符号

\n   换行
\r   回车
\t   制表符 四个空格
\b   退格

printf

打印命令,后加字符串

eval

执行多个命令

exec

不创建子进程,执行后续命令,且执行完毕,自动exit

shell子串

${变量}                   返回变量值
${#变量}                  返回变量长度,字符长度
${变量:start}             返回start索引之后的字符
${变量:start:length}      返回start索引之后的length长度的字符
${变量#word}              从变量开头删除最短匹配的word子串
${变量##word}             从变量开头删除最长匹配的word
${变量%word}              从变量结尾删除最短匹配的word
${变量%%word}             从变量结尾删除最长匹配的word
${变量/pattern/string}    用string代替第一个匹配的pattern
${变量//pattern/string}   用string代替所有匹配的pattern

特殊shell扩展变量

如果parameter变量值为空,返回word字符串
${parameter:-word}

如果parameter变量值为空,则word替代变量值,且返回其值
${parameter:=word}

如果parameter变量值为空,word当做stderr输出,否则输出变量值
用于设置变量为空导致错误时,返回的错误信息
${parameter:?word}

如果parameter变量值为空,什么都不错,否则word返回
${parameter:+word}

循环

for循环

# 数组
ARR=("70.182.58.148" "70.182.58.149" "70.182.58.150")

# 循环
for i in "${ARR[@]}"; do
  echo $i
done

for循环+索引

# 数组
ARR=("70.182.58.148" "70.182.58.149" "70.182.58.150")

# 循环
for index in $(seq 0 $((${#ARR[@]}-1))); do
  echo $index
  echo ${ARR[$index]}
done