我想养只狗

博客园 首页 联系 订阅 管理

shell编程-开发人员使用

作为开发人员,为什么要学习shell?

  1. 需要看懂运维人员编写的Shell程序。

  2. 偶尔会编写一些简单的Shell程序来管理集群、提高开发效率。

Shell概述

  1. Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。

  2. Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。

Shell解析器

  1. Linux提供的Shell解析器有:cat /etc/shells

/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

  1. Centos默认的解析器是bash:echo $SHELL

/bin/bash

脚本入门

脚本格式

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

helloworld

  1. 编写脚本:vi helloworld.sh

!/bin/bash

echo "hello shuaige"

  1. 执行脚本:
  • bash或sh 脚本的相对路径或绝对路径:

    sh或bash /home/helloworld.sh

    sh或bash helloworld.sh

  • 脚本的绝对路径或相对路径(必须具有可执行权限)

    ./helloworld.sh

    /home/helloworld.sh

# 查看脚本
[linux@localhost datas]$ cat helloworld.sh 
#!/bin/bash
echo "hello shuaige"

# 执行脚本方式1
[linux@localhost datas]$ bash helloworld.sh 
hello shuaige

# 执行脚本方式2
[linux@localhost datas]$ ./helloworld.sh
-bash: ./helloworld.sh: 权限不够

知识拓展:

  1. 第一种执行方法本质是bash解析器执行脚本,所以脚本本身不需要执行权限。第二种执行方法本质是脚本需要自己执行,所以需要执行权限。

  2. pwd 查看目录 mkdir 创建文件夹 touch 新建文件 cat 查看内容

  3. 权限不够修改办法:chmod 777 helloworld.sh(最高权限)

多命令处理

#!/bin/bash
cd /home/linux/
touch banzhang.txt
echo "I LOVE YOU" >> banzhang.txt

Shell中的变量

常用系统变量

$HOME $PWD $SHELL $USER

[linux@localhost datas]$ echo $HOME
/home/linux
[linux@localhost datas]$ echo $PWD
/home/linux/datas
[linux@localhost datas]$ echo $SHELL
/bin/bash
[linux@localhost datas]$ echo $USER
linux

自定义变量

基本语法

  1. 定义变量:变量=值 等号两边不能留有空格
  2. 撤销变量:unset 变量
  3. 输出变量:echo $变量
  4. 声明静态变量: readonly 变量,注意:不能unset
[linux@localhost datas]$ D="A B C"
[linux@localhost datas]$ echo $D
A B C
  1. 可把变量提升为全局变量,可供其他shell程序使用
    export 变量

知识拓展:

  1. 变量名称可以由字母、数字和下划线组成,但不能以数字开头,环境变量名建议大写

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

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

特殊变量

$n

  • $n:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}。
#!/bin/bash
echo "$0 $1 $2 $3"

$#

  • $# (功能描述:获取所有输入参数个数,常用于循环)
#!/bin/bash
echo "$0 $1 $2 $3"
echo $#

$*和$@

  • $* (描述:代表命令行中所有的参数,把所有参数看成一个整体)
  • $@ (描述:也代表命令行中所有的参数,不过把每个参数区分对待)
[linux@localhost datas]$ bash parameter.sh test1 test2
parameter.sh test1 test2 
2
test1 test2
test1 test2

$?

  • $? 最后一次执行的命令的返回状态。如果为0,表示上一条命令执行正确;为非0,则上一条命令执行不正确。

运算符

  1. $((运算式)) 或 $[运算式]

  2. expr +,-,*,/,% 加减乘除取余

expr运算符间要有空格

# 计算2+3
[linux@localhost datas]$ expr 2 + 3
5

# 计算(2+3)*4
## 方式1
[linux@localhost datas]$ expr `expr 2 + 3` \* 4
20

## 方式2
[linux@localhost datas]$ s=$[(2+3)*4]
[linux@localhost datas]$ echo $s
20
## 方式3
[linux@localhost datas]$ s=$(((2+3)*4))
[linux@localhost datas]$ echo $s
20

条件判断

基本语法

  • [condition] (注意 condition前后要有空格)

注意:条件非空即为true,[ pqh ]返回true,[]返回false。

常用判断条件

两个整数之间比较

符号 描述
-lt (less than)小于
-le (less equal) 小于等于
-eq (equal)等于
-gt (greater than) 大于
-ge (greater equal) 大于等于
-ne (not equal) 不等于

文件权限判断

  • -r 有读的权限(read)
  • -w 有写的权限(write)
  • -x 有执行的权限(execute)

文件类型判断

  • -f 文件存在并且是一个常规文件(file)
  • -e 文件存在(existence)
  • -d 文件存在病是一个目录(directory)
# 判断23是否大于2
[linux@localhost datas]$ [ 23 -gt 2 ]
[linux@localhost datas]$ echo $?
0

# 判断helloworld.sh是否有写入权限
[linux@localhost datas]$ [ -w hellowrld.sh ]
[linux@localhost datas]$ echo $?
1

# 判断目录中文件是否存在
[linux@localhost datas]$ [ -e /home/linux/datas ]
[linux@localhost datas]$ echo $?
0

多条件判断

  • 多条件判断:[ condition ] && echo OK || echo notok

    • &&:上一条命令执行成功时,才执行下一条命令。

    • ||:上一条命令执行失败后,才执行下一条命令。

流程控制

IF判断

[linux@localhost datas]$ cat if.sh
#!/bin/bash
if [ $1 -eq 1 ]
then
    echo "我真帅"
elif [ $1 -eq 2 ]
then
    echo "我真丑"
fi
[linux@localhost datas]$ bash if.sh 2
我真丑

注意事项:

  1. 中括号和条件判断式之间必须有空格。

  2. if后要有空格。

case 语句

[linux@localhost datas]$ cat case.sh
#!/bin/bash
case $1 in
1)
    echo "小班"
;;
2)
    echo "中班"
;;
3)
    echo "大班"
;;
esac
[linux@localhost datas]$ bash case.sh 2
中班

注意事项:

  1. case行尾必须为单词“in”,每个模式匹配必须以“)”结束。

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

  3. 最后的“*)”表示默认模式,相当于java中的default。

for循环

语法1

[linux@localhost datas]$ cat for.sh
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
    s=$[$s+$i]    
done
echo $s
[linux@localhost datas]$ bash for.sh
5050

语法2

[linux@localhost datas]$ cat for2.sh
#!/bin/bash
for i in $*
do
    echo $i
done
[linux@localhost datas]$ bash for2.sh 1 2
1
2

WHILE循环

[linux@localhost datas]$ cat while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
    s=$[$s + $i]
    i=$[$i + 1]
done
echo $s

[linux@localhost datas]$ bash while.sh
5050

注意事项:

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

read读取控制台输入

read(选项)(参数)
  • -p 指定读取值时的提示符
  • -t 指定读取值时等待的时间(秒)
# 提示7秒内,读取控制台输入的名称
[linux@localhost datas]$ cat read.sh
#!/bin/bash
read -t 7 -p "在7s内请输入你的名字:" NAME
echo $NAME
[linux@localhost datas]$ bash read.sh
在7s内请输入你的名字:帅哥
帅哥

函数

系统函数

basename命令:

删掉所有的前缀包括最后一个'/'字符,然后将字符串显示出来。

## 基本语法
basename [string / pathname] [suffix] 
# 方式1
[linux@localhost datas]$ basename /home/linux/banzhang.txt
banzhang.txt

# 方式2
[linux@localhost datas]$ basename /home/linux/banzhang.txt .txt
banzhang

注意事项:

suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

dirname命令:

从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径。

## 基本语法
dirname 文件绝对路径
[linux@localhost datas]$ dirname /home/linux/banzhang.txt
/home/linux

自定义函数

# 格式
[ function ] funname[()]
{
    Action:
    [return int;]
}
funname

注意事项:

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

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

# DESC 计算输入两个参数的值
[linux@localhost datas]$ cat sum.sh
#!/bin/bash
function sum(){
    s=0;
    s=$[$1 + $2]
    echo $s
}
read -p "input your param1:" P1
read -p "input your param2:" P2
sum $P1 $P2
[linux@localhost datas]$ bash sum.sh
input your param1:1
input your param2:2
3

shell工具(重点)

cut

cut命令从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出

  • 基本用法cut [选项参数] filename

    • -f 列号,提取第几列

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

# DESC 切割cut.txt第一列
[linux@localhost datas]$ cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
[linux@localhost datas]$ cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le

# DESC 获取第三行第一个单词
[linux@localhost datas]$ cat cut.txt | grep guan | cut -d " " -f 1
guan

sed

sed是一种流编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,成为“模式空间”,接着sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,知道文件末尾,文件内容并没有改变,除非你使用重定向存储输出

  • 基本语法sed [选项参数] ‘command’ filename

  • 选项参数:

    • -e 直接在指令列模式上进行sed的动作编辑
  • 命令功能:

    • a 新增,a的后面可以接字串,在下一行出现。

    • d 删除

    • s 查找并替换

# DESC 在第二行后增加mei nv字符
[linux@localhost datas]$ sed -e "2a mei nv" sed.txt
dong zhen
guan zhen
mei nv
wo wo
lai lai
# 将sed.txt文件中的第二行删除并将wo替换为ni
[linux@localhost datas]$ sed -e '2d' -e 's/wo/ni/g' sed.txt

注意事项:

加g(global)表示全部替换,不加只替换第一个。

awk

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

  • 基本用法:awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename

    • pattern:表示AWk在数据中查找的内容,就是匹配模式。

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

注意:只有匹配了pattern的行才会执行action。

  • 选项参数

    • -F 指定输入文件分隔符

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

## 将etc目录下的passwd拷贝到当前路径下。
[root@iZ8vbjebgszspdkm85w9a4Z learn]# cp /etc/passwd ./
[root@iZ8vbjebgszspdkm85w9a4Z learn]# 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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
www:x:1000:1000::/home/www:/sbin/nologin
mysql:x:1001:1001::/home/mysql:/sbin/nologin
redis:x:1002:1002::/home/redis:/sbin/nologin
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F: '/^root/{print $7}' passwd
/bin/bash
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F: '/^root/{print $1","$7}' passwd
root,/bin/bash
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F: '{print $1","$7}' passwd
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
systemd-network,/sbin/nologin
dbus,/sbin/nologin
polkitd,/sbin/nologin
sshd,/sbin/nologin
postfix,/sbin/nologin
chrony,/sbin/nologin
nscd,/sbin/nologin
tcpdump,/sbin/nologin
rpc,/sbin/nologin
rpcuser,/sbin/nologin
nfsnobody,/sbin/nologin
ntp,/sbin/nologin
www,/sbin/nologin
mysql,/sbin/nologin
redis,/sbin/nologin
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F: 'BEGIN{print "user,shell"} {print $1","$7} END{print "wozhenshuai, bin/shizhiminggui"}' passwd
user,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
systemd-network,/sbin/nologin
dbus,/sbin/nologin
polkitd,/sbin/nologin
sshd,/sbin/nologin
postfix,/sbin/nologin
chrony,/sbin/nologin
nscd,/sbin/nologin
tcpdump,/sbin/nologin
rpc,/sbin/nologin
rpcuser,/sbin/nologin
nfsnobody,/sbin/nologin
ntp,/sbin/nologin
www,/sbin/nologin
mysql,/sbin/nologin
redis,/sbin/nologin
wozhenshuai, bin/shizhiminggui
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F : '{print $3}' passwd
0
1
2
3
4
5
6
7
8
11
12
14
99
192
81
999
74
89
998
28
72
32
29
65534
38
1000
1001
1002
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk -F : -v i=1 '{print $3+i}' passwd
1
2
3
4
5
6
7
8
9
12
13
15
100
193
82
1000
75
90
999
29
73
33
30
65535
39
1001
1002
1003
  • action内置变量
变量 说明
FILENAME 文件名
NR 已读的记录数
NF 浏览记录的域的个数(切割后,列的个数)
[root@iZ8vbjebgszspdkm85w9a4Z learn]# 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
passwd,7,7
passwd,8,7
passwd,9,7
passwd,10,7
passwd,11,7
passwd,12,7
passwd,13,7
passwd,14,7
passwd,15,7
passwd,16,7
passwd,17,7
passwd,18,7
passwd,19,7
passwd,20,7
passwd,21,7
passwd,22,7
passwd,23,7
passwd,24,7
passwd,25,7
passwd,26,7
passwd,27,7
passwd,28,7
[root@iZ8vbjebgszspdkm85w9a4Z learn]# cat sed.txt
dong shen
guan zhen

wo wo
lai lai
le le 
[root@iZ8vbjebgszspdkm85w9a4Z learn]# awk '/^$/ {print NR}' sed.txt
3

sort

sort 命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出

sourt [选项] (参数)
参数 描述
-n 依照数值大小排序
-t 以相反的顺序排序
-t 设置排序时使用的分隔字符
-k 指定需要排序的列
[root@iZ8vbjebgszspdkm85w9a4Z learn]# cat sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
[root@iZ8vbjebgszspdkm85w9a4Z learn]# 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@iZ8vbjebgszspdkm85w9a4Z learn]# sort -t : -nk 2 sort.sh
cls:10:3.5
bd:20:4.2
ss:30:1.6
bb:40:5.4
xz:50:2.3

——非原创,本笔记根据“尚硅谷大数据技术之shell”视频教程学习记录,并参考了其他人的学习笔记

posted on 2023-02-17 15:57  我想养只狗  阅读(67)  评论(0)    收藏  举报