ActPi向阳技术栈
← 返回文章列表

Shell 脚本零碎笔记2

文章目录
  1. 一个纯bash实现外部命令的脚本集合
  2. 读取文件到一个字符串中
  3. 创建一个空文件
  4. 字符串处理
  5. 长度
  6. 改变大小写
  7. 花括号展开
  8. 释伴声明
  9. 命令替换
  10. 获取系统的主机名
  11. 获取操作系统的架构(32位或64位)
  12. 获取操作系统/内核的名称
  13. 获取当前的工作目录
  14. 获取脚本运行的秒数
  15. 进度条

一个纯bash实现外部命令的脚本集合

读取文件到一个字符串中

替代 cat 命令.

file_data="$(<"file")"

创建一个空文件

替代 touch.

# 简短的方式.
>file

值得参考的基础教程:阮一峰 Bash 脚本教程

字符串处理

字符串提取子串 ${varname:offset:length} 返回变量$varname的子字符串,从位置offset开始(从0开始计算),长度为length。

$ count=frogfootman
$ echo ${count:4:4}
foot
## test.jpg 删除后缀.jpg 返回 test
${filename%.*}
## ${branch#*/} 表示删除 $branch 变量中第一个斜杠(/)及其左侧的所有字符
$branch=origin/test
${branch#*/}=test

文件名仅允许字母、数字、横杠与下划线的组合

if [[ ${filename} =~ ^[a-zA-Z0-9_-]*[.] ]];then
    echo -e "\033[32m---文件名校验ok---\033[0m"
else
    echo  -e "\033[31m ERROR:有特殊字符、请检查!\033[0m" && exit -1
fi

长度

`${#VAR}` 字符变量的长度.
`${#ARR[@]}` 数组的长度.

改变大小写

参数 它将做什么?
${VAR^} 大写第一个字符.
${VAR^^} 大写所有字符.
${VAR,} 小写第一个字符.
${VAR,,} 小写所有字符.
${VAR~} 反转第一个字符.
${VAR~~} 反转所有字符.

花括号展开

# 符号: {<START>..<END>}

# 打印 1-100 之间的数字.
echo {1..100}

# 打印一个范围内的浮点数.
echo 1.{1..9}

# 打印a-z间的字符.
echo {a..z}
echo {A..Z}

# 嵌套.
echo {A..Z}{0..9}

# 打印用零填充的数字.
echo {01..100}

# 更改步长.
# 符号: {<START>..<END>..<INCREMENT>}
echo {1..10..2} # 每次增加2.

释伴声明

使用 #!/usr/bin/env bash 而不是 #!/bin/bash.

  • 前者搜索用户的 PATH 以查找 bash 二进制文件.
  • 后者假设它始终安装在 /bin/ 目录,可能导致问题.
# 正确的方式:

    #!/usr/bin/env bash

# 错误的方式:

    #!/bin/bash

命令替换

使用 $()而不是 ` `.

# 正确的方式.
var="$(command)"

# 错误的方式.
var=`command`

# $() 很容易嵌套,而``不能.
var="$(command "$(command)")"

获取系统的主机名

"$HOSTNAME"

# NOTE: 这个变量可能是空的.
# (可选):将失败调用设置为hostname命令
"${HOSTNAME:-$(hostname)}"

获取操作系统的架构(32位或64位)

"$HOSTTYPE"

获取操作系统/内核的名称

这可用于条件判断不同的操作系统,而无需调用uname

"$OSTYPE"

获取当前的工作目录

这是内置pwd的替代方案。

"$PWD"

获取脚本运行的秒数

"$SECONDS"

进度条

这是一种绘制进度条的简单方法,无需在函数本身中使用for循环。

示例函数:

bar() {
    # 用法: bar 1 10
    #           ^----- 已经完成的百分比 (0-100).
    #             ^--- 字符总长度.
    ((elapsed=$1*$2/100))

    # 创建空格表示的进度条
    printf -v prog  "%${elapsed}s"
    printf -v total "%$(($2-elapsed))s"

    printf '%s\r' "[${prog// /-}${total}]"
}

示例用法:

for ((i=0;i<=100;i++)); do
    # 纯粹的暂停动作 (为了本例可以更好的演示).
    (:;:) && (:;:) && (:;:) && (:;:) && (:;:)

    # Print the bar.
    bar "$i" "10"
done

printf '\n'