1.shell 概述
1.shell历史
○命令解析器
○终端下输入一个字符串 - 回车
○去对应的路径下查找该字符串(命令)- PATH
○如果有执行对应路径下的命令
sh - unix
bash - linux
2.shell脚本
○shell命令
大部分都在 /bin
将命令写入文件,执行这个文件
命令解析器逐行解析
○shell命令的集合
加载循环和判断语句
3.shell结构
○#!指定执行脚本的shell
○#注释行
脚本作用
创建修改时间
作者
○命令和控制结构
#! /bin/bash
#注释
#注释
echo "helloworld"
ls
pwd
ps aux
4.创建shell程序的步骤:
○创建一个包含命令和控制结构的脚本文件
○修改文件权限, 使它可以执行
○执行
./hello.sh
sh hello.sh
添加执行权限
chmod u+x test.sh
./test.sh
sh test.sh
5.shell脚本解析方式
○逐行解析
2.shell基本语法
1.变量
○环境变量
env
○本地变量 - 自定义的变量
变量定义:
□shell中的变量没有数据类型 - 默认值都是string类型
□VAR=hello or VAR=“hello”
□注意事项:
定义shell变量的时候,建议变量名大写
赋值的时候=前后不能有空格
用export命令可以把本地变量导出为环境变量
□export VARNAME or export VARNAME=value
○位置变量
$0 - 相当于C语言main函数的argv[0]
$1、$2...
□相当于C语言main函数的argv[1]、argv[2]...
○特殊变量
$#: 这个程序的参数个数
$*: 表示参数列表"$1" "$2" ...
$@: 表示参数列表"$1" "$2" ...
$$: 这个程序的PID
$?: 执行上一个命令的返回值
□$@ $*
一般情况下一样
"$@" "$" 不一样
◊for循环时候"$" 将所有的参数作为一个整体
◊for循环时候"$@" 有多少个参数被拆分成几部分
2.set/unset命令
○set
显示当前Shell进程中定义的所有变量(包括本地变量和环境变量)和函数
○unset
可以删除已定义的环境变量或本地变量
unset VARNAME
3.命令代换
○将执行完命令之后得到的数据保存到变量
○取值
VAR=shell命令
VAR=$(shell命令) -- 常用,推荐使用
4.算术代换
○对变量取值
在变量的前边加 $
□$VAR
○对变量做算术运算
算术运算: +-/
算术运算操作的必须是整数
VAR=$(($VAR10))
VAR=$[$VAR-10]
○进制运算
$[base#n]
□base - 进制
□#连接符
□n:数值
□$[2#11]
5.转义字符
○
将有特殊意义的字符变成普通字符
将普通字符变成有特殊意义的字符 - 正则表达式中使用
6.单引号
○VAR='$(date)'
单引号中的内容原样输出
7.双引号
○VAR="$(date)"
会继续双引号中的命令, 输出结果字符串
3.shell脚本语法 - 条件测试
1.条件测试命令
○test
○[ ] - test一样
○[[ ]]
注意事项:
[]或者[[]]中的数据和括号的左右需要有一个空格的间隔
□[ -d filename ]
2.如何判断条件是否成立?
○如果返回值为0:成立
○返回值为非0: 不成立
3.文件状态测试
a. linux中的文件种类: 7种
普通文件:-
□find安装文件类型查找:普通文件 f
目录: d
符号链接: l
套接字:s
管道:p
字符设备:c
块设备:b
-b filename 当filename 存在并且是块文件时返回真(返回0)
-c filename 当filename 存在并且是字符文件时返回真
-d pathname 当pathname 存在并且是一个目录时返回真
-e pathname 当由pathname 指定的文件或目录存在时返回真
-f filename 当filename 存在并且是正规(普通)文件时返回真
-g pathname 当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真
-h/-L filename 当filename 存在并且是符号链接文件时返回真 (或 filename)
-k pathname 当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真
-p filename 当filename 存在并且是命名管道时返回真
-r pathname 当由pathname 指定的文件或目录存在并且可读时返回真
-s filename 当filename 存在并且文件大小大于0 时返回真
-S filename 当filename 存在并且是socket 时返回真
-t fd 当fd 是与终端设备相关联的文件描述符时返回真
-u pathname 当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真
-w pathname 当由pathname 指定的文件或目录存在并且可写时返回真
-x pathname 当由pathname 指定的文件或目录存在并且可执行时返回真
-O pathname 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写)
-G pathname 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真
file1 -nt file2 file1 比file2 新时返回真
file1 -ot file2 file1 比file2 旧时返回真
f1 -ef f2 files f1 and f2 are hard links to the same file
常见字符串测试
-z string 字符串string 为空串(长度为0)时返回真
-n string 字符串string 为非空串时返回真
str1 = str2 字符串str1 和字符串str2 相等时返回真
str1 == str2 同 =
str1 != str2 字符串str1 和字符串str2 不相等时返回真
5.常见的数值测试
○==: eq --- equal
○!=: ne -- not equal
○ >: gt -- greater than
○>=: ge -- greater than equal
○ <: lt less than>
○<=: le -- less than equal
nt1 -eq int2 如果int1 等于int2,则返回真
int1 -ne int2 如果int1 不等于int2,则返回真
int1 -lt int2 如果int1 小于int2,则返回真
int1 -le int2 如果int1 小于等于int2,则返回真
int1 -gt int2 如果int1 大于int2,则返回真
int1 -ge int2 如果int1 大于等于int2,则返回真
6.测试时使用的逻辑操作符
○a - && : and
○o - ||: or
取反:!
-a 逻辑与,操作符两边均为真,结果为真,否则为假。
-o 逻辑或,操作符两边一边为真,结果为真,否则为假。
! 逻辑否,条件为假,结果为真。
7.test , [] , [[]]
○test 和 [ 是 bash 的内部命令
○[[ 是 bash 程序语言的关键字!
○绝大多数情况下,这个三个功能通用。但是命令和关键字总是有区别的。
○区别:
在 [[ 中使用 && 和 ||
[ 中使用 -a 和 -o 表示逻辑与和逻辑或
shell脚本语法 - 分支
if/then/elif/else/fi
○ 语法格式
if [ 条件判断语句 ];then
处理语句
处理语句
fi
if [ 条件判断语句 ] then
处理语句
处理语句
fi
if [ 条件判断语句 ];then
处理语句
处理语句
elif [ 条件判断语句 ] then
处理语句
处理语句
else
处理语句
处理语句
fi
○ :空命令
§ :"是一个特殊的命令,称为空命令,
§ 该命令不做任何事,但Exit Status总是真。
§ if :; then
xxxx
fi
case/esac
○ 基本语法:
case 变量 in
yes|Yes|y|Y)
处理语句
处理语句
;;-- break
处理语句
;; -- break
No|no|n|N)
处理语句
处理语句
;;
*)
处理语句
;;
esac
image.png
image.png
5.shell脚本语法 - 循环
1.for/do/done
○语法格式
for 变量 in list(列表);do控制语句
控制语句
done
2.while/do/done
○语法格式
while [ 条件测试语句 ];do
控制语句
控制语句
done
○举例:
登录的时候,输入密码,如果输入有误,提示用户再次输入
□需要使用shell中的函数:
read - 阻塞读终端,将输入到终端的数据存储到变量中
read VAR
image.png
3.break和continue
○break 可以选择跳出的层数
break n
6.输入和输出
1.echo
○echo 字符串
○-e:解析字符串中的\n字符
○-n:去掉echo默认加上的换行符
2.文件重定向
○cmd > file
file - 文件名
○cmd >> file
内容追加到file文件中
○cmd > file 2>&1
cmd 1 > file 2 > &1
1文件 &1文件描述符
□1 -> stdout_fileno
6.awk
1.处理行和列,主要用于列的处理
○awk缺省的行分隔符是换行
○缺省的列分隔符是连续的空格和Tab
如何取出每一列
□$0: 当前行,还没有拆分
□$1: 第一列
□$2: 第二列
□。。。。。
ps aux | awk '{print $2}'
如果不是缺省的如何指定分隔符
□-F:
□-F后边跟的就是指定的分隔符
练习:
□拆分一下/etc/passed
2.一般格式
○awk 参数 '/pattern/{actions}' 目标文件
awk -F/ '/^g/{print $3}' test
○awk 参数 'condition{actions}' 目标文件
condition -- 条件
□特殊条件
BEGIN
◊awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd
END
pattern -- 正则表达式
actions -- 匹配成功后的一系列操作
○awk 参数 脚本文件 目标文件
3.如何定义变量
○需要变量直接写即可,默认值0
○定义变量的时候直接指定一个初始值
awk -v x=10 '条件/正则表达式{action} ' 文件名
4.练习:
○从ps aux得到的数据中找出pid>1000 && pid <2000的进程的个数
ps aux | awk '$2>1000 && $2<2000{print $2}'
ps aux | awk '$2>1000 && $2<2000{x=x+1;}END{print x}'