Shell 常规知识点归纳整理<一>

记录整理一下目前遇到的shell相关的用法, 还不错,加深一些印象。

Shell $0 $? $! 变量解析

参数 含义
$$ Shell本身的PID(ProcessID)
$! Shell最后运行的后台Process的PID
$? 最后运行的命令的结束代码(返回值)
$- 使用Set命令设定的Flag一览
$* 所有参数列表。如"$*"用「"」括起来的情况、以"?$1 ?$2 … $n"的形式输出所有参数
$@ 所有参数列表。如"$@"用「"」括起来的情况、以"?$1" "?$2" … "$n" 的形式输出所有参数
$# 添加到Shell的参数个数
$0 Shell本身的文件名
$1~$n 添加到Shell的各参数值。$1是第1参数、$2是第2参数…

$* 取当前shell的所有参数,将所有的命令行视为单个字符串,相当于"$1?$2"
$@ 取当前shell的所有参数保留参数里的空白,,相当于$1,$2,一般用其进行参数传递

#!/bin/sh 
echo "Args Count:$#" 
echo "Process ID:$$" 
echo "Arg 0:$0" 
echo "Arg 1:$1" 
echo "Arg 2:$2" 
echo "Args List:$@" 
echo "Args List2:$*" 

for i in "$*";do
echo $i
done

echo "******"
for i in "$@";do
echo $i
done

"""
Args Count:3
Process ID:84735
Arg 0:./echo.sh
Arg 1:hello
Arg 2:pretty
Args List:hello pretty world
Args List2:hello pretty world
hello pretty world
******
hello
pretty
world
"""

Shell中冒号的作用

: 就是什么也不做(do nothing)即空命令,一般用在 if...then... 条件中,用作什么也不做的命令,类似python 的PASS or continue之类的jump动作。

if [ -f "$0" ]; then
    :
else
    echo ‘the file do not exit !‘
fi

Shell中多行注解反注解:

方法一:#,使用vim 进行多行注解,vim支持块处理

1.Ctrl+v进入visual block模式, 调整上下选中注解行(j 或者k也可以上下移动)

2.按shift+i(或者大写I),输入注释符(#或//),按一下或者两下Esc

3.反注解同理,control+V进入VISUAL BLOCK模式,按j或k选中多行,按l选中多列,按x或者d删除注释。

方法二:

冒号在Bash里也是一个命令,表示啥都不做,<<是输入重定向,两个EOF(可用其它特殊成对字符替代)之间的内容通过<<追加给冒号(:),但是冒号对它们啥都不做,就相当于没做任何处理和输出,就相当于注释了。

:<<EOF
echo "--1-- "
echo "--2--"
EOF
echo "Done"

AWK 中NR NF $NF的含义

NR表示已经读取域的记录数目,直观的含义是第几行

NF表示浏览记录的域的个数

awk ‘{print $1}’打印第一列

awk ‘{print $2}’打印第二列

NF表的是列数

如:a b c d

那么NF=4

$NF****就是表示第五列的值,就是一行数据最后一列的那个值

echo "a b c d" |awk ‘{print NF}‘
4
echo "a b c d" |awk ‘{print $0}‘
a b c d
echo "a b c d" |awk  ‘{print $1}‘
a
echo "a b c d" |awk  ‘{print $2}‘
b
echo "a b c d" |awk  ‘{print $3}‘
c
echo "a b c d" |awk  ‘{print $4}‘
d
echo "a b c d" |awk  ‘{print $NF}‘
d

打印每行的行号,每行的列数(以空格区分列),对应的完整行内容

cat ~/Desktop/echo.sh |awk ‘{print NR,NF,$0}‘
1 1 #!/bin/sh 
2 3 echo "Args Count:$#" 
3 3 echo "Process ID:$$" 
4 3 echo "Arg 0:$0" 
5 3 echo "Arg 1:$1" 
6 2 sleep 3
7 3 echo "Arg 2:$2" 
8 3 echo "Args List:$@" 
9 3 echo "Args List2:$*" 
10 3 echo "Args ?。?:$-" 
11 0 
12 0 
13 1 :<<EOF
14 3 echo "--1-- "
15 2 echo "--2--"
16 1 EOF
17 2 echo "Done1"
18 0 
19 6 if [ -f "$0" ]; then
20 1     :
21 1 else
22 7     echo ‘the file do not exit !‘
23 1 fi

获取输出内容or文件多少行

1. df -h |awk ‘{print NR}‘ |tail -n1 #df -h 输出磁盘信息

2. awk ‘{print NR}‘ ~/Desktop/echo.sh|tail -n1

3. awk ‘END{print NR}‘ ~/Desktop/echo.sh 

4. sed -n ‘$=‘ ~/Desktop/echo.sh  or df -h |sed -n ‘$=‘

5. cat ~/Desktop/echo.sh |wc -l

打印指定第几行第几列

df -h |awk ‘NR==5{print $5}‘ #第五行第五列

shell if条件判断参数

参考shell脚本--条件判断参数

Tips:

&&:用来执行条件成立后执行的命令
||:用来执行条件不成立后的执行命令

常规的变量引入,只需要$var即可,但如果有单引号扩起来的字符串,想引入变量,那么引入单引号即可取值

a=1;echo $a;echo ‘‘$a‘‘

判断变数是否为数字

if [ -z "$(echo $var | sed ‘s#[0-9]##g‘)" ];then
	echo "Is Number"
else 
	echo "Not a Number:${var}"
fi

格式1: test 条件表达式
格式2: [ 条件表达式 ]
格式3: [[ 条件表达式 ]] 支持正则 =~
注意:
[ ] 和 [[ ]] 两边必须有空格

  • 1.判断文件类型
判断参数 含义
-e 判断文件是否存在(任何类型文件)
-f 判断文件是否存在并且是一个普通文件
-d 判断文件是否存在并且是一个目录
-L 判断文件是否存在并且是一个软连接文件
-b 判断文件是否存在并且是一个块设备文件
-S 判断文件是否存在并且是一个套接字文件
-c 判断文件是否存在并且是一个字符设备文件
-p 判断文件是否存在并且是一个命名管道文件
-s 判断文件是否存在并且是一个非空文件(有内容)
cd ~/Desktop 
Desktop % [ -s echo.sh ] && echo ‘非空‘ || echo "空"
非空
Desktop % [ -s echo1.sh ] && echo ‘非空‘ || echo "空"
空
Desktop % [ -f echo1.sh ] && echo ‘文件存在‘ || echo "不存在"
不存在
Desktop % [ -f echo.sh ] && echo ‘文件存在‘ || echo "不存在" 
文件存在
  • 2.判断文件权限
判断参数 含义
-r 当前用户对其是否可读
-w 当前用户对其是否可写
-x 当前用户对其是否可执行
-u 是否有suid,高级权限冒险位
-g 是否sgid,高级权限强制位
-k 是否有t位,高级权限粘滞位
  • 3.判断文件新旧
判断参数 含义
file1 -nt file2 比较file1是否比file2新
file1 -ot file2 比较file1是否比file2旧
file1 -ef file2 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
Desktop % ln echo.sh echo_1.sh
Desktop % [ echo.sh -ef echo_1.sh ] && echo yes || echo no
yes
Desktop % [ echo.sh -ef echo_2.sh ] && echo yes || echo no
no
Desktop % [ echo.sh -ef echo2.sh ] && echo yes || echo no
yes
  • 4.判断整数
判断参数 含义
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
#!/bin/bash
# 磁盘空间警报脚本
count=$(df -h |sed -n ‘$=‘)
for ((i=2; i<=$count; i++))
do
    disk_name=`df -h |awk ‘NR==‘$i‘{print $1}‘`
    disk_use=$(df -h |awk ‘NR==‘$i‘{print $5}‘|awk -F"%" ‘{print $1}‘)
    if [ -z "$(echo $disk_use | sed ‘s#[0-9]##g‘)" ];then
        if [ $disk_use -gt 90 ];then
		    echo "`date +%F-%H` disk warning...\t${disk_name} use:${disk_use}% " 
        fi
    fi
done
  • 5.判断字符串
判断参数 含义
-z 判断是否为空字符串,字符串长度为0则成立
-n 判断是否为非空字符串,字符串长度不为0则成立
string1 = string2 判断字符串是否相等
string1 != string2 判断字符串是否不等
  • 6.多重条件判断
判断符号 含义 举例
-a 和 && 逻辑与 [ 1 -eq 1 -a 1 -ne 0 ] 或[ 1 -eq 1 ] && [ 1 -ne 0 ]
-o 和 || 逻辑或 [ 1 -eq 1 -o 1 -ne 1 ] 或[ 1 -eq 1 ] || [1 -ne 1]

&& 前面的表达式为真,才会执行后面的代码
|| 前面的表达式为假,才会执行后面的代码
; 只用于分割命令或表达式

数值比较

[ $(id -u) -eq 0 ] && echo "the user is root" || echo "the user is not root"

补充

test 、[ ] 和[[ ]]的区别

test命令通常做判断, test 命令和 [ ] 等同

可用于判断某个条件是否为真。可用于 字符串,数值和文件的测试。

 [ "$A" = "$B"  ]        	                	##是否相等
 [  "$A" != "$B"  ]        	                ##是否不相等
 [  "$A" -eq "$B"  ]      	                ##是否相等
 [  "$A" -ne "$B"  ]       	                ##是否不相等
 [  "$A" -le "$B"  ]       	                ##是否小于等于
 [  "$A" -lt "$B"  ]                        ##是否小于
 [  "$A" -ge "$B "  ]                       ##是否大于等于
 [  "$A" -gt "$B"  ]                        ##是否大于
 [  "$A" -ne "$B" -a "$A" -gt "$B"  ]       ##A 不等于 B 并且 A 大于B
 [  "$A" -ne "$B" -o "$A" -gt "$B"  ]       ##A不等于B 或者  A大于B
 [  -z "$A"  ]                              ##是否为空
 [  -n "$A"  ]                              ##是否不为空

a=1;b=1
test "$a" = "$b" && echo yes || echo no
yes
[ "$a" = "$b" ] && echo yes || echo no
yes
test "$a" != "$b" && echo yes || echo no
no
[ "$a" != "$b" ] && echo yes || echo no
no

参考[shell中(),[]和[[]]的区别](https://developer.aliyun.com/article/318988)

  1. 首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
    "[[",是关键字,许多shell(如ash bsh)并不支持这种方式。ksh, bash(据说从2.02起引入对[[的支持)等支持。
    "["是一条命令, 与test等价,大多数shell都支持。在现代的大多数sh实现中,"["与"test"是内部(builtin)命令,换句话说执行"test"/"["时不会调用/some/path/to/test这样的外部命令(如果有这样的命令的话)。

  2. [[]]结构比Bash版本的[]更通用。在[[和]]之间的所有的字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。

    用[[ ... ]]测试结构比用[ ... ]更能防止脚本里的许多逻辑错误。比如说,&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构会发生错误。

  3. (( ))结构扩展并计算一个算术表达式的值。如果表达式值为0,会返回1或假作为退出状态码。一个非零值的表达式返回一个0或真作为退出状态码。这个结构和先前test命令及[]结构的讨论刚好相反。

  4. [ ... ]为shell命令,所以在其中的表达式应是它的命令行参数,所以串比较操作符">" 与"<"必须转义,否则就变成IO改向操作符了(请参看上面2中的例子)。在[[中"<"与">"不需转义;
    由于"[["是关键字,不会做命令行扩展,因而相对的语法就稍严格些。例如
    在[ ... ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ ... ]]则不允许这样做。

  5. [[ ... ]]可以进行算术扩展,支持正则表达式

正则判断

检查变数是否包含三位数字

var="123d"
re="^[0-9]{3,}"
if [[ $var =~ $re ]]; then
    echo "true"
else
    echo "not true"
fi

Shell 常规知识点归纳整理<一>

上一篇:【Linux】awk文本替换


下一篇:E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用) E: 无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?