shell笔记

shell概述

 

 shell是命令行解释器,接受外层应用程序、用户的命令然后调用操作系统的内核,最终控制硬件

 

[root@yangdong ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

sh是bash的软连接,sh调用的是bash 

[root@yangdong ~]# cd /bin
[root@yangdong bin]# ll|grep bash
-rwxr-xr-x. 1 root root       964600 8月   8 2019 bash
lrwxrwxrwx. 1 root root           10 4月   3 12:30 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root         6964 8月   8 2019 bashbug-64
lrwxrwxrwx. 1 root root            4 4月   3 12:30 sh -> bash

bash解析shell文本

[root@yangdong bin]# echo $SHELL
/bin/bash

 

 shell脚本入门

脚本格式

脚本以#!/bin/bash开头(指定解析器)

#!/bin/bash
echo "hello world"

 shell脚本的后缀名是.sh

执行shell脚本使用命令bash/sh XXX.sh可以借助bash直接执行

也可以赋予执行权限后使用./执行

使用sh/bash执行脚本本质是bash解析器帮你执行脚本,所以脚本不需要执行权限

./本质是脚本需要自己执行,所以需要执行权限


[root@yangdong shelltest]# vim frist  
[root@yangdong shelltest]# sh frist.sh
sh: frist.sh: 没有那个文件或目录
[root@yangdong shelltest]# mv frist frist.sh
[root@yangdong shelltest]# sh frist.sh 
hello world
[root@yangdong shelltest]# ./frist.sh
-bash: ./frist.sh: 权限不够
[root@yangdong shelltest]# chmod 777 frist.sh 
[root@yangdong shelltest]# ./frist.sh
hello world

多命令处理

#!/bin/bash
cd /shelltest
touch banzhang.txt
echo "i love cls">>banzhang.txt
[root@yangdong shelltest]# vim batch.sh
[root@yangdong shelltest]# bash batch.sh 
[root@yangdong shelltest]# cat banzhang.txt 
i love cls

 

shell中的变量

常用系统变量

$HOME $PWD $SHELL $USER

[root@yangdong shelltest]# echo $HOME
/root
[root@yangdong shelltest]# echo $PWD
/shelltest
[root@yangdong shelltest]# echo $SHELL
/bin/bash
[root@yangdong shelltest]# echo $USER
root

自定义变量

[root@yangdong shelltest]# A=1
[root@yangdong shelltest]# echo $A
1

删除自定义变量

[root@yangdong shelltest]# unset A
[root@yangdong shelltest]# echo $A

声明静态变量 readonly,不能unset

[root@yangdong shelltest]# readonly B=3
[root@yangdong shelltest]# echo $B
3
[root@yangdong shelltest]# unset B
-bash: unset: B: 无法反设定: 只读 variable

环境变量名建议大写

等号两边不能有空格

在bash中变量默认都是字符串类型,无法直接进行数值运算

[root@yangdong shelltest]# C=1+1
[root@yangdong shelltest]# echo $C
1+1

变量的值如果有空格需要使用单引号或者双引号括起来

[root@yangdong shelltest]# D= banzhang love mm
bash: banzhang: 未找到命令...
[root@yangdong shelltest]# D=" banzhang love mm "
[root@yangdong shelltest]# echo $D
banzhang love mm

可以把变量提升为全局变量,可供其他shell程序使用

在frist.sh文件中添加echo $D

#!/bin/bash
echo "hello world"
echo $D
[root@yangdong shelltest]# ./frist.sh 
hello world

[root@yangdong shelltest]# echo $D
banzhang love mm

export D把D提升为全局变量 

[root@yangdong shelltest]# export D
[root@yangdong shelltest]# ./frist.sh 
hello world
banzhang love mm

特殊变量

$n(n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,第十个以上的参数使用{}${10})

#!/bin/bash
echo "$0 $1 $2 $3"
[root@yangdong shelltest]# sh parameter.sh 
parameter.sh   
[root@yangdong shelltest]# sh parameter.sh banzhang
parameter.sh banzhang  
[root@yangdong shelltest]# sh parameter.sh banzhang love
parameter.sh banzhang love 
[root@yangdong shelltest]# sh parameter.sh banzhang love mm
parameter.sh banzhang love mm
[root@yangdong shelltest]# sh parameter.sh banzhang love mm hehe
parameter.sh banzhang love mm

$#(获取所有输入参数个数,常用于循环)

#!/bin/bash
echo "$0 $1 $2 $3"
echo $#
[root@yangdong shelltest]# sh parameter.sh banzhang love mm hehe
parameter.sh banzhang love mm
4
[root@yangdong shelltest]# sh parameter.sh banzhang love mm 
parameter.sh banzhang love mm
3

$*(命令行中所有参数,$*把所有参数看成一个整体)

$@(命令行中所有参数,$@把每个参数区分对待)

#!/bin/bash
echo "$0 $1 $2 $3"
echo $#
echo $*
echo $@
root@yangdong shelltest]# sh parameter.sh banzhang love mm 
parameter.sh banzhang love mm
3
banzhang love mm
banzhang love mm
[root@yangdong shelltest]# sh parameter.sh 1 2 3 4
parameter.sh 1 2 3
4
1 2 3 4
1 2 3 4

$?(描述最后一次执行命令的返回状态。返回0证明上一次命令正确执行,非0证明上一个命令执行不正确)

[root@yangdong shelltest]# echo $?
0

 

 

 运算符

基本语法

"$((运算式))"或者"$[运算式]"

expr + - \* / %

[root@yangdong shelltest]# expr 3+2
3+2
[root@yangdong shelltest]# expr 3 + 2
5
[root@yangdong shelltest]# expr 3 +2
expr: 语法错误

[root@yangdong shelltest]# s=$[(2+3)*4]
[root@yangdong shelltest]# echo $s
20

 

条件判断 

[ condition ]condition前后要有空格,条件非空返回true,[]返回false

[root@yangdong shelltest]# [ 23 -gt 22 ]
[root@yangdong shelltest]# echo $?
0
[root@yangdong shelltest]# [ 23 -le 22 ]
[root@yangdong shelltest]# echo $?
1
[root@yangdong shelltest]# 

常用判断条件

= 字符串比较

-lt 小于(less than)

-le小于等于(less equal)

-eq等于(equal)

-gt大于(greater than)

-ge大于等于(greater equal)

-ne 不等于(not equal)

文件权限判断

-r可读(read)

-w 可写(write)

-x可执行(execute)

[root@yangdong shelltest]# [ -w frist.sh ]
[root@yangdong shelltest]# echo $?
0
[root@yangdong shelltest]# [ -x frist.sh ]
[root@yangdong shelltest]# echo $?
0

文件类型判断

-f文件存在并且是一个常规文件(file)

-e文件存在(existence)

-d文件存在并且是一个目录(directory)

[root@yangdong shelltest]# [ -e frist.sh ]
[root@yangdong shelltest]# echo $?
0
[root@yangdong shelltest]# [ -f frist.sh ]
[root@yangdong shelltest]# echo $?
0
[root@yangdong shelltest]# [ -d frist.sh ]
[root@yangdong shelltest]# echo $?
1

多条件判断

&&表示前一条命令执行成功时才执行后一条命令

||上一条命令执行失败后才执行下一条命令

[root@yangdong shelltest]# [ condition ]&&echo ok||echo notok
ok
[root@yangdong shelltest]# [ condition ]&&[]||echo notok
bash: []: 未找到命令...
notok

 

流程控制 

if语法

if [  条件判断式 ];then

              程序

fi

if [  条件判断式 ]

     then

           程序

fi

注意事项:

[  条件判断式 ],中括号和条件判断式之间必须有空格

if后要有空格

#!/bin/bash
if [ $1 -eq 1  ]
then
echo "bzzs"
elif [ $1 -eq 2  ]
then
echo "clszm"
fi
[root@yangdong shelltest]# sh second.sh 1
bzzs
[root@yangdong shelltest]# sh second.sh 2
clszm

case语法

case $变量名 in

"值 1")

如果变量的值等于值1,则执行程序1

;;

"值 2")

如果变量的值等于值2,则执行程序2

;;

*)

如果变量的值都不是以上的值,则执行此程序

;;

esac

case行尾必须为单词in,每一个模式匹配必须以右括号“)”结束

双分号“;;”表示命令序列结束,相当于java的break

*)表示默认模式,相当于java的default

#!/bin/bash
case $1 in
1)
echo "banzhang"
;;
2)
echo "cls"
;;
*)
echo "renyao"
;;
esac
[root@yangdong shelltest]# sh case.sh 2
cls
[root@yangdong shelltest]# sh case.sh 3
renyao
[root@yangdong shelltest]# sh case.sh 1
banzhang

for语法

for(( 初始值;循环控制条件;变量变化))

   do

       程序

done

#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[ $s+$i ]
done
echo $s
[root@yangdong shelltest]# sh for.sh 
5050

 for i in $*/$@

do

程序

done

#!/bin/bash
for i in $*
do
echo "cls love $i"
done
[root@yangdong shelltest]# sh forin.sh banzhang lala lili lily
cls love banzhang
cls love lala
cls love lili
cls love lily

while语法

while [  条件判断式 ]

do

程序

done

#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
[root@yangdong shelltest]# sh while.sh 
5050

 

read读取控制台输入 

read语法

read(选项)(参数)

选项

-p 指定读取值时的提示符

-t 指定读取值时等待的时间

参数

        变量:指定读取值时的变量名

#!/bin/bash
read -t 10 -p "请输入你的名字在10秒之内" NAME
echo $NAME
[root@yangdong shelltest]# sh read.sh 
请输入你的名字在10秒之内111111111111
111111111111

 

函数 

系统函数

basename:截取路径生成文件名

[root@yangdong shelltest]# basename /shelltest/while.sh
while.sh
[root@yangdong shelltest]# basename /shelltest/while.sh .sh
while

dirname:截取文件绝对路径

[root@yangdong shelltest]# dirname /shelltest/while.sh 
/shelltest

自定义函数

基本语法

[ function ] funname[()]

{

 Action;

[return int;]

}

funname

必须在调用函数地方之前先声明函数,shell脚本是逐行运行,不会像其他语言一样先编译

函数返回值只能通过$?系统变量获得,可以显示加return返回,如果不加将以最后一条命令运行结果作为返回值,return后跟数值n(0-255)

#!/bin/sh
function sum(){
s=0;
s=$[ $1+$2 ]
echo $s
}
read -p "请输入参数1:" P1
read -p "请输入参数2:" P2
sum $P1 $P2
[root@yangdong shelltest]# sh sum.sh 
请输入参数1:3
请输入参数2:4
7

 

shell工具 

cut:在文件中负责剪切数据,从文件中的每一行剪切字节,字符,字段,并将这些字节字符字段输出

cut [选项参数] filename

默认分隔符是制表符

-f 列号,提取第几列

-d 分隔符,按照指定分隔符分割列

dong shen
guan zhen
wo wo
lai lai
le le
[root@yangdong shelltest]# cut -d " " -f 2 cut.txt
shen
zhen
wo
lai
le
[root@yangdong shelltest]# cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
dong shen
guan zhen
wo   wo
lai   lai
le    le


[root@yangdong shelltest]# cut -d " " -f 2,3,4,5 cut.txt
shen
zhen
  wo
  lai
   le

[root@yangdong shelltest]# cat cut.txt | grep guan
guan zhen
[root@yangdong shelltest]# cat cut.txt | grep guan | cut -d " " -f 1
guan

选取系统PATH变量值第二个“:”开始后的所有路径
[root@yangdong shelltest]# echo $PATH
/usr/local/libexec/git-core:/usr/local/bin:/opt/apache-maven-3.6.3/bin:/opt/jdk1.8.0_141/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

[root@yangdong shelltest]# echo $PATH | cut -d : -f 3-
/opt/apache-maven-3.6.3/bin:/opt/jdk1.8.0_141/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin


sed流编辑器,一次处理一行内容,处理时把当前处理的行存储在临时缓冲区中,接着使用sed命令处理缓冲区中的内容,处理完成后把缓冲区的内容送往屏幕,接着处理下一行,不断重复,直到文件末尾,文件内容没有改变,除非使用重定向存储输出

sed 【选项参数】‘command‘ filename

选项参数

-e 直接在指令模式上进行sed的动作编辑

命令

a 新增,a的后面添加字符串,在下一行出现

d 删除

s查找并替换

在第二行添加


[root@yangdong shelltest]# cat cut.txt
dong shen
guan zhen
wo   wo
lai   lai
le    le
[root@yangdong shelltest]# sed "2a mei   nv" cut.txt
dong shen
guan zhen
mei   nv
wo   wo
lai   lai
le    le



 删除wo

[root@yangdong shelltest]# cat cut.txt
dong shen
guan zhen
wo   wo
lai   lai
le    le
[root@yangdong shelltest]# sed "/wo/d" cut.txt
dong shen
guan zhen
lai   lai
le    le

把wo替换为ni   g表示全局替换 

[root@yangdong shelltest]# cat cut.txt
dong shen
guan zhen
wo   wo
lai   lai
le    le
[root@yangdong shelltest]# sed "s/wo/ni/g" cut.txt
dong shen
guan zhen
ni   ni
lai   lai
le    le

 删除第二行并且把wo替换为ni 


[root@yangdong shelltest]# cat cut.txt
dong shen
guan zhen
wo   wo
lai   lai
le    le

[root@yangdong shelltest]# sed -e "2d" -e "s/wo/ni/g" cut.txt
dong shen
ni   ni
lai   lai
le    le

awk文本分析工具,把文件逐行的读入,以空格为默认的分隔符将每行切片,切开的部分再进行分析处理

awk【选项参数】 ‘pattern{action} pattern2{action2}。。。’ filename

pattern 表示awk在数据中查找的内容,就是匹配模式

action 在找到匹配内容时所执行的一系列命令

选项参数

-F 指定输入文件,拆分隔符

-v 赋值一个用户定义变量

awk内置变量

FILENAME 文件名

NR 已读记录数

NF 切割后列的个数

 

在passwd文件中 以:为分隔符,以root为开头匹配,以“,”分割,打印第一列和第七咧

[root@yangdong shelltest]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin


[root@yangdong shelltest]# awk -F : '/^root/ {print $1","$7}' passwd
root,/bin/bash

 在passwd文件中,以:为分割,在第一行添加user,shell,打印第一列和第七列,在最后一行添加 dahaige,/bin/zuishuai

begin在所有数据读取行之前执行,end是在所有数据执行之后执行

[root@yangdong shelltest]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync



[root@yangdong shelltest]# awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "dahaige,/bin/zuishai"}' passwd
user,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
dahaige,/bin/zuishai

 在passwd文件中,以:为分割,定义变量i=1,打印第三列,并且数值加1

[root@yangdong shelltest]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin


[root@yangdong shelltest]# awk -F : -v i=1 '{print $3+i}' passwd
1
2
3
4

 在passwd文件中,以:为分割,打印passwd文件名,每行的行号,每行的列数

[root@yangdong shelltest]# awk -F : '{print FILENAME "," NR "," NF}' passwd
passwd,1,7
passwd,2,7
passwd,3,7
passwd,4,7
passwd,5,7
passwd,6,7

sort将文件进行排序,并将排序结果标准输出

sort(选项)(参数)

选项

-n 依照数值大小排序

-r 以相反的顺序来排序

-t 设置排序时所用的分割字符

-k 指定需要排序的列

参数:指定待排序的文件列表

 

对sort.sh文件以:为分隔符,指定第二列,以数值大小反序排列

[root@yangdong shelltest]# cat sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6

[root@yangdong shelltest]# sort -t : -nrk 2 sort.sh
xz:50:2.3
bb:40:5.4
ss:30:1.6
bd:20:4.2
cls:10:3.5
[root@yangdong shelltest]# sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值