SHELL简介
Shell就是一种命令解析器 也是一门变成语言,即shell脚本,shell是解释执行的脚本语言,可直接调用linux命令.shell脚本的本质,就是大量shell命令的组合,并写入一个文本文件中
创建脚本
#!/bin/bash(指定解析器)echo "hello world"touch 1.txt 2.txt 3.txtls -l > 1.txt
执行脚本
第一种方式 分配执行权
chmod u+x helloworld.sh
./helloworld.sh
/mysh/helloworld.sh
第二种方式 可以没有执行权
bash helloworld.sh
shell helloworld.sh
变量
系统变量
使用set可以查看所有系统变量
BASH=/bin/bash
HOME=/root
HOSTNAME=linux01
JAVA_HOME=/opt/apps/jdk1.8.0_191
PATH=/usr/local/sbin:/usr/local
自定义变量
变量定义
变量名=变量值 #注意不能有空格
删除变量
unset 变量名
声明常量 readonly变量,不能使用unset变量
name=zss
name=1ss
age=23
gender=M
readyonly username=Ly 不可变的变量 常量
取值
$name
${name}
"$name"
'$name' ----> $name的字符串
注意字符串的拼接
echo $name lss
echo ${name} lss
echo "$name"aaa lssaaa ""号中取变量的值可以正常取出
echo '$name'aaa $nameaaa ''号中取不出来变量的值 就是$name字符串 单引号会将所有特殊字符脱意
删除只读变量
yum -y install gdb
cat << EOF|gdb
attach $$
call unbind_variable("sex")
detach
EOF
unset User
export和source
export username=lisi 将变量的范围作用在所有的子bash中
source 将子bash定义的变量 作用在当前bash
export 修饰的变量的作用域是 当前和所有的子进程
source 将子进程中的变量 拉取到当前
特殊变量
$1 $2 $n ${10} 接收单个参数
$* 接收所有参数
$@ 接收所有参数
$# 参数的个数
$? 接收上个命令执行的结果 0 执行成功 非0的是执行失败
接收单个参数 一直到$9都可以 10以上 ${10}
vi args01.sh
#!/bin/bash
echo "接收的所有参数$1 $2 $3"
touch $1 $2 $3
sh args01.sh 1.txt 2.txt 3.txt
vi args02.sh
#!/bin/bash
echo "接收参数的个数$*"
echo "接收参数的个数$#"
touch $*@
#!/bin/bash
echo "接收参数的个数$@"
echo "接收参数的个数$#"
touch $@
sh args02.sh 1.java 2.java
read交互
#!/bin/bash
read -t 10 -p '请输入您的用户名:' username用来接收用户输入的用户名 -t 10代表10秒不输入就退出
read -t 10 -p '请输入您的密码:' password
echo "$username"
echo "$password"
算数运算
expr 1+1 #错误 1 + 1 之间必须有空格
expr 1 + 1
expr 1 + 1 \* 2 由于*有特殊含义 需要转义
expr `expr 1 + 2` \* 3
$((1+1))
$(((1+2)*3))
$[1+1]
$[(1+2)*3]
${a} 取变量a的值
$() 取一个命令的结果
$(( )) 取算术运算表达式的运算结果 $[]相同
条件判断
&&和||
&&:用来执行条件成立后执行的命令
||:用来执行条件不成立后的执行命令
ping windows && echo yes || echo no #windows能ping通 输出yes 不能ping通输出no
ls && echo yes || echo no ls执行成功 输出yes 执行不成功输出no
整数测试
注意 符号 两边要有空格
test 1 = 1 && echo yes || echo no 1 == 1
test 1 != 1 && echo yes || echo no 1 != 1
test 1 -eq 1 && echo yes || echo no 1 == 1
test 1 -ne 1 && echo yes || echo no 1 != 1
test 1 -gt 2 && echo yes || echo no 1 > 2
test 1 -lt 2 && echo yes || echo no 1 < 2
test 1 -ge 2 && echo yes || echo no 1 >= 2
test 1 -le 2 && echo yes || echo no 1 <= 2
两个整数之间比较
-eq 等于 -ne 不等于
-lt 小于 -le 小于等于
-gt 大于 -ge 大于等于
a=1
b=2
test $a = $b && echo yes || echo no
test $a != $b && echo yes || echo no
test $a && echo yes || echo no a存在 输出 yes 不存在输出no
test $a -a $a = 1 && echo yes || echo no yes
test $a -a $a = 2 && echo yes || echo no no
test $a -o $a = 2 && echo yes || echo no yes
test命令通常做判断, test 命令和 [ ]等同
#前后必须有空格
[1 = 1] && echo yes || echo no 错误
[ 1 = 1 ] && echo yes || echo no 正确
字符串测试
test "abc" == "bcd" && echo yes || echo no 判断字符串是否相等 注意 == 两边要有空格
test "abc" != "bcd" && echo yes || echo no 判断字符串不相同
判断字符串不是null
test $abc && echo yes || echo no abc 存在 输出 yes 不存在输出 no
判断字符串是null
test -z $abc && echo yes || echo no abc不存在 输出yes 存在输出 no
[ $abc ] && echo yes || echo no 不是空 yes 是空 no
文件测试
-d 判断是否是文件夹
-f 判断是否是文件
-L 判断是否是超链接
-e 判断是否存在
-r 判断是否有读权限
-w 判断是否有写权限
-x 判断是否有执行权
test -d 1.txt && echo yes || echo no
[ -d 1.txt ] && echo yes || echo no
[ -f 1.txt ] && echo yes || echo no
[ -e 1.txt ] && echo yes || echo no
[ -L /bin ] && echo yes || echo no
[ -r 1.txt -a -w 1.txt ] && echo yes || echo no
[ -x 1.txt ] && echo yes || echo no
if语句判断
单条件判断
if [ 条件 ]
then
执行
fi
互斥条件判断
if [ 条件 ]
then
程序
else
程序
else
程序
fi
多条件判断
if [ 条件1 ]
then
执行
elif [ 条件2 ]
then
执行
...
else
执行
fi
-a && 逻辑与
-o || 逻辑或
case选择语句
#!/bin/bash
read -p '请输入一个数字(1-7):' NUM
case $NUM in
1)
echo "星期一"
;;
....
*)
echo "输错了"
;;
esac
for循环
for (( 初始化表达式;布尔表达式;步进表达式 ))
do
程序
done
for 变量 in 值1 值2 值3
do
程序
done
或者写成一行
for 变量 in 值1 值2 值3 ; do 程序 ; done
while循环
while [ 条件判断式 ]
do
程序
...
done
数组
定义数组
arr=(1 2 3 4 5 "abc");
为数组元素赋值
arr[0]=100
arr[1]=200
根据指定索引获取元素
${arr[索引]}
获取数组中所有元素
${arr[*]}
${arr[@]}
获取数组的长度
${#arr[*]}
${#arr[@]}
遍历数组
for n in ${arr[*]}
do
echo $n
done
写成一行 for n in ${arr[*]};do echo $n;done
函数
系统函数
basename 命令会删掉所有的前缀包括最后一个 ('/')字符,然后将字符串显示出来
basename /mysh/for.sh ---->for.sh
basename -s .sh/mysh/for.sh ---->for 不显示后缀
basename /mysh --->mysh
basename -a /aaa/b.txt/ccc/d.txt ----> b.txt d.txt
dirname 从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
dirname /mysh/a.txt ---->a.txt
dirname /mysh/1.txt /aaa/b.txt ----> /mysh /aaa
自定义函数
function 函数名(){
函数体
return 返回值
}
注意:
function可以省略不写
()可以省略不写 但是函数名和{}之间要有空格
return可以结束函数
return默认返回最后一个命令的状态,也可以给定参数值 范围在 0-255
如果没有return 默认返回最后一个指令的退出状态值 $?
定时任务
crontab -e
* * * * *
分 时 日 月 周
* * * * * 代表每分钟
1 * * * * 每小时的01分执行
1 14 * * * 每天的14点01分执行
1 14 1 * * 每月1号的14点01分执行
1 14 2 7 * 每年7月2号的14点01分执行
1 14 * 7 2 每年7月的每周的第二天 14点01分执行
高级文本编辑工具
cut
cut -d 指定切割方式 -f 第几列 文件名
sed
sed [选项参数] 'command' filename
awk
awk [选项参数] 'pattern1{action1} pattern2{action2}...'
filename
pattern: 表示AWK在数据中查找的内容,就是匹配模式
action: 在找到匹配内容时所执行的一系列命令
-F 指定输入文件折分搁符
-v 赋值一个用户定义变量
内置变量
FILENAME 文件名
NR 已读的记录数 第几行
NF 浏览记录的域的个数 (切割后,列的个数) 切割的列数
sort
sort 参数 文件
-n 以数值的方式排序 不指定以字符串形式排序
-r 逆序
-t 指定分隔符
-k 指定列
