SHELL简介

Shell就是一种命令解析器 也是一门变成语言,即shell脚本,shell是解释执行的脚本语言,可直接调用linux命令.shell脚本的本质,就是大量shell命令的组合,并写入一个文本文件中

创建脚本

  1. #!/bin/bash(指定解析器)
  2. echo "hello world"
  3. touch 1.txt 2.txt 3.txt
  4. ls -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 指定列