一、Shell的执行方式

  • bash script.shsh scripte.sh ,文件本身没权限执行,没x权限,则使用的方法,或脚本未指定 shebang ,重点推荐的方式
  • 使用 绝对/相对 路径执行脚本,需要文件含有x权限
  • source script.sh 或者 . script.sh ,代表 执行的含义,source等于点.

通常,可以把一些函数定义在一个文件,通过 source 或者 . 的方式引入当前 shell 环境进行使用,以实现了结构化设计。

二、变量 无引号、双引号、无引号、反引号

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

推荐用双引号,特殊字符转义

三、特殊变量

  • $0 获取shell脚本文件名,以及脚本路径
  • $n 获取shell脚本的第n个参数,n在1~9之间,如$1 ,$2, $9 ,大于9则需要写,${10},参数空格隔开
  • $# 获取执行的shell脚本后面的参数总个数
  • $* 获取shell脚本所有参数,不加引号等同于$@作用,加上引号”$*”作用是 接收所有参数为单个字符串,”$1 $2..” $@ 不加引号,效果同上,加引号,是接收所有参数为独立字符串,如”$1” “$2” “$3” …,空格保留
  • $? 上一次命令执行状态返回值,0正确,非0失败,也可以用来获取函数返回值
  • $$ 当前shell脚本的进程号
  • $! 上一次后台进程的PID
  • $_ 再次之前执行的命令,最后一个参数

函数接收的参数也可以用$1、$#、$*等

四、变量大括号内操作

  • ${变量} 返回变量值

  • ${‘#’变量} 计算变量count(忽略引号)

  • ${变量:start}

  • ${变量:start:length}

  • ${变量#word} 从变量开头删除最短匹配的word子串

  • ${变量##word} 从变量开头,删除最⻓匹配的word

  • ${变量%word} 从变量结尾删除最短的word

  • ${变量%%word} 从变量结尾开始删除最⻓匹配的word

  • ${变量/pattern/string} 用string代替第一个匹配的pattern

  • ${变量//pattern/string} 用string代替所有的pattern

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

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

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

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

五、数值计算

1.通过let、$(()) 和 []计算
  • let a=a+1,或者 let “a=a+1”
  • a=$((a+1))
  • num=5;echo $[num*2]

Shell默认是字符串操作,如果不用专门的计算符都是字符串拼接。
不管是 let 还是双小括号,内部对变量的引用不需要$符号也能识别,当然加了也没关系。
记住[]里面不需要$,计算结果需要$,类似(())

2.通过expr bc计算

判断文件名是否符合要求

1
2
3
#!/bin/bash
# 模式匹配计算个数
expr yc.jpg ":" ".*\.jpg"
1
2
3
4
5
6
#!/bin/bash
if expr $1 : ".*\.jpg" &> /dev/null; then
echo "This is a jpg file"
else
echo "This is not a jpg file"
fi

expr参数列表必须要要有空格,特殊字符要转义
整数的计算,用双小括号,let,expr。小数的计算只能用bc,例如echo 4.5-1.1|bc。

计算 1..10 的和

1
2
3
4
echo {1..10}|tr " " "+"|bc

# xargs配合管道符能把前一个输出作为后一个命令的输入
echo {1..10} | sed 's/ / + /g'|xargs expr
3.通过awk 计算

前面的输入空格分割作为awk的参数,可以用来计算

1
echo "4 8"|awk '{print ($1+4*$2)}'

六、条件判断

1.不用 if 的情况
1
[ -f /etc/passwd ] && cat /etc/passwd || echo "not exist"
2.if
1
2
3
4
if xxx; then
elif xxx; then
else
fi
3.test、 []、 [[]]和(())

test 命令最短的定义可能是评估一个表达式; 如果条件为真,则返回一个 0 值。如果表达式不为真,则返回一个大于 0 的值 — 也可以将其称为假值。检查最后所执行命令的状态的最简便方法是使用 $? 值。
[] 命令左右必须要有空格
[[]]和(()) 不常用,提供正则匹配或者计算符

  • -d 目录是否存在
  • -f 文件是否存在
  • -r 文件是否有读权限, -s 文件是否是空白文件
  • 两个数值判定 -gt -lt -ge根据对应英文联想即可
  • 两个字符串判定 = !=
  • test 多重判断 -a and -o or, test -r filename -a -x filename
  • [] 多重判断 && ||

注意bash只能处理整数

4.case循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

name="$0"
case $1 in
s|start)
echo "start ..."
;;
stop)
echo "stop ..."
;;
reload)
echo "reload ..."
;;
*)
echo "Usage:$name [start|reload|stop]"
exit 1
;;
esac
exit 0
5.for循环
1
2
3
4
5
6
#!/bin/bash

for test in a b c d
do
echo "$test"
done

for 的元素用空格,但是有特殊字符的最好还是用双引号,或者转义符号转义一下

1
2
3
4
5
6
7
#!/bin/bash

# for test in I am “no't” Alien
for test in I am no\'t Alien
do
echo "$test"
done
1
2
3
4
5
6
7
#!/bin/bash

# for test in I am “no't” Alien
for test in I am no\'t Alien
do
echo "$test"
done
6.while循环
1
2
3
4
5
6
7
8
#!/bin/bash

var1=10
while [ $var1 -gt 0 ]
do
echo $var1
let var1=var1-1
done

六、函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
func1(){
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1

echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi

函数内部的变量如果和外部重名,需要加 local,不然外部变量会被覆盖

七、三剑客处理文本(持续更新)

“Shell 三剑客” 是一个常用的术语,用于指代 grep、awk 和 sed。

  1. grep:全称是Global Regular Expression Print,表示全局正则表达式版本。这是一个强大的文本搜索工具,它可以使用正则表达式搜索文本,并打印出匹配的行。
  2. awk:这是一个强大的文本分析工具,它可以扫描和处理输入的文本行和列。awk 在处理列分隔数据时尤其有用。
  3. sed:Stream Editor 的缩写,它是一个用来进行文本替换、插入和删除等操作的流编辑器。