第九章Linux系统管理-Linux Shell编程基础

第九章Linux系统管理

Linux  Shell编程基础

概述

Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的系统级程序。Shell本身是一个用C语言编写的程序,功能强大,易编写,易调试,灵活性强。它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。

Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。

由于习惯的原因,简洁起见,本文出现的 "shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身。

9.1 Linux Shell编程基础与Shell环境

Shell分类:

Bourne Shell:sh、ksh、Bash、psh

C Shell:csh、tcsh

Linux主要是Bash,unix主要是ksh。

9.11 常用Echo

Echo 选项 “输出内容”

选项:-e 支持反斜杠控制符
\a:输出警告音
\n:换行符
\r:回车符
\b:退格键
\t:水平制表符
\v:垂直制表符
\x:16进制ASCII码输出字符
echo “hello itpux" 显示hello world

[root@Redhat7 ~]# echo "Learning is painful"

Learning is painful

9.1.2 别名alias

shell别名:

alias 查看系统中已有的别名

alias ls=‘ls -lsa’

设置别名,要永久生效需将该命令放入~/.bashrc文件或~/.bash_profile中

unalias ls 删除别名

 

 

9.1.3 Bash shell中常用快捷键:

Ctrl+c 强制终止

Ctrl+l 清屏

Ctrl+u 从光标位置删到行首

Ctrl+a 从光标位置移到行首

Ctrl+e 从光标位置移到行尾

Ctrl+z 命令放到后台

 

9.1.4 shell多命令执行

命令1;命令2 分号;表示多个命令顺序执行

命令1&&命令2 逻辑与,命令1执行正确则执行命令2,命令1执行错误则不执行2

命令1||命令2 逻辑或,命令1执行正确则不执行2,命令1执行不正确则执行命令2

9.1.5 SHELL重定向


01.标准输出重定向

命令 > 文件

命令 >> 文件 覆盖的方式写入

追加的方式写入

 

02.标准错误输出重定向      

错误命令 2> 文件

错误命令 2>> 文件     (注意:2和>之间无空格)

 

03.正确和错误信息同时重定向

命令 > 文件 2>& 1

命令 >> 文件 2>& 1

命令 &>> 文件

命令 >> 文件1 2>> 文件2 正确和错误信息分开保存

ls -lsa > /dev/null

不想要的打印信息全部重定向到/dev/null下,输入到此的文件全被系统丢掉

 

04.输入重定向

wc < 1.log 统计文件中的行数、单词书、字节数

 

 

9.1.6 Shell管道符:

命令1| 命令2 : 命令1的正确输出作为命令2的输入

例:

ls -lh /etc | more

用more命令分屏显示ls的输出结果

ps –ef|grep LOCAL=NO

查看进程,grep从搜索结果中查看LOCAL=NO的进程

ps –ef|grep LOCAL=NO| wc –l

查看进程,grep从搜索结果中查看LOCAL=NO的进程 ,并统计行数

 

9.1.7 SHELL通配符:

? 匹配任意一个字符

* 匹配任意内容

[] 匹配括号内任意一个字符

[0-9] -表示范围,匹配其中一个

[^0-9] 逻辑非^,匹配非括号内内容

Bash中其它符号:

$ 调用变量的值

\ 转义符,跟在\之后的特殊符号将失去特殊含义,如 \* 就是输出*号

# Shell中表示注释

$() 用来引用系统命令

=变量赋值

==测试相等

 

9.1.8 SHELL中用到的特殊文件:

/dev/null

它等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什

么也读不到. 然而 /dev/null对命令行和脚本都非常的有用.

nohup ./start.sh >/dev/null &

/dev/zero 会提供无穷无尽的0,它可以给文件写入无穷无尽的0

dd if=/dev/zero of=itpux.txt bs=1M count=10

/dev/tty 系统当前终端

cat 1.txt > /dev/tty

/dev/console 代表的系统控制台,错误信息和诊断信息都会被到这个上。

cat 1.txt > /dev/tty

9.1.9 BASH SHELL变量

用户自定义变量、环境变量、位置变量、预定义变量。

1、用户自定义变量

只能作用于当前Shell,变量取值都是一个字符串

DAY=date “=”左右两边不能有空格

DAY=“today is date” 若含有空格,则需要加双引号

echo $DAY $调用变量,echo打印输出

unset DAY 删除变量

set 该命令查看系统所有变量

2、环境变量

全局的,所有Shell都可以调用的变量

export DAY=date export命令就是将变量导出为环境变量

env env命令是查看系统所有的环境变量

环境变量PATH:为系统命令搜索的路径。

PATH="$PATH":/usr/sbin 即添加/usr/sbin目录也为PATH变量,若想要永久更改环境

变量,需要修改环境变量配置文件。

3、变量参数

$n n为数字,$0代表命令本身,$1-$9代表第1-9个参数,10以上的需要用大括号

${10}

$* 代表命令行中所有参数,$*把所有参数当做一个整体

$@ 代表命令行所有参数,$@把每个参数区分对待

$# 代表命令行中参数的个数

$? 最后一次执行的命令的返回状态。若为0,则表示命令执行正确;若为非0,

代表上一条指令执行错误。

$$ 当前进程的进程ID号

$! 后台运行的最后一个进程的进程号

 

4、环境变量配置文件

4.1 souce命令 修改配置文件后使之生效

souce 配置文件

或者 .配置文件

如:souce /etc/profile ; ./.bash_profile

 

4.2 常用环境变量配置文件:

/etc/profile

/etc/profile.d/*.sh

~/.bash_profile

~/.bashrc

/etc/bashrc

 

4.3 其他环境变量配置文件

01.注销时生效的文件:~/.bash_logout 如可以在每次注销时清空历史命令,将history

-c写入该文件(但一般不建议)

02.历史命令保存文件:~/.bash_history

03.本地Shell登录欢迎信息:/etc/issue

该文件中用到的转义符,/d显示当前系统日期,/s操作系统名称,/m硬件体系结构,/r内

核版本,/t系统时间,/l登录的终端

号,/o域名,/n主机名

04.远程登录欢迎信息:/etc/issue.NET

要显示此信息,需要SSH配置文件/etc/ssh/sshd_config中要加入“Banner /etc/issue.Net”

05.登录欢迎信息:etc/motd

不管是本地还是远程登录都能显示此信息。

9.2 Linux Shell正则表达式基础讲解

1、什么是正则表达式?

简单的说,正则表达式就是为处理大量的字符串而定义的一套规则和方法。通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤、替换或者输出需要的字符串。linux正则表达式一般以行为单位处理的。

2、为什么要学正则表达式

在企业工作中,我们每天做的linux运维工作中,时刻都会面对大量带有字符串的文本配置、程序、命令输出及日志文件等,而我们经常会有迫切的需要从大量的字符串内容中查找符合工作需要的特定字符串,这就要靠正则表达式,因此,可以说正则表达式就是为过滤这样字符串的需求而生的!

3、容易混淆的两个注意事项:

1)linux正则表达式一般是以行为单位处理的。

2)正则表达式和我们常用的通配符特殊字符是有本质区别的,例如:ls *.txt 这里的*就是通配符(表示所有),不是正则表达式。

 

正则表达式就是为了处理大量的文本|字符串而定义的一套规则和方法

通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤,替换或输出需要的字符串。Linux正则表达式一般以行为单位处理。

简单说为处理大量文本|字符串而定义的一套规则和方法,以行为单位出来,一次处理一行。

最常应用正则表达式的命令是grep(egrep),sed,awk。

9.2.1 正则表达式与通配符区别 

01、通配符(* ? [])用来匹配符合条件的文件名,是完全匹配。

 ls、find、cp这些命令不支持正则表达式,支持通配符匹配。

 02、正则表达式用来匹配在文件中的字符串,是包含匹配。

 grep、awk、sed等命令支持正则表达式。

9.2.2 基础正则表达式

01、“*”前一个字符匹配0次或任意多次

“a*” 匹配所有内容,包括空格

“ab*” 匹配包含ab、ab123、ab123...等字符的字符串,“*”只对b起作用

“abc*” 匹配包含abc、abc123、abc123...等字符的字符串

02、“.”匹配除了换行符外任意一个字符

“s..d” 匹配s和d之间有两个字符的

“ s.*d ” 匹配s和d之间有任意多字符

03、“^”匹配行首,“$”匹配行尾

“^a” 匹配以a开头的行

“$a” 匹配以a结尾的行

“^$” 匹配空白行

04、[]匹配中括号中指定的任意一个字符

“a[bcd]f” 匹配abf、acf、adf中的一个

“^[0-9]” 匹配数字开头的行

05、[^]匹配空号中字符以外的一个字符

“^[^0-9]” 匹配以非数字开头的行

“^[^a-zA-Z]” 匹配非字母开头的行

06、“\”转义字符,使之后的一个特殊字符变为普通字符

“\*” 就是普通字符*

“\$$” 匹配以$结尾的行

07、“\{n\}”匹配前面字符出现n次的字符串

“a\{4\}” 连续出现4个a的行

“[0-9]\{4\}” 连续出现4个数字的行,不一定完全一样的数字

“a\{2,5\}” a最少出现2次,至多出现5次的行

例:

“[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}” 匹配格式为1990-02-10的日期

“[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}” 匹配格式为192.168.1.106

的IP地址

 

9.2.3 cut命令

cut命令用于列提取,默认分隔符是tab键。

选项:-d指定分隔符,-f指定提取第几列

例:cut -d ":" -f1 /etc/passwd

为:为分隔符提取文件的第一列

grep "/bin/bash" /etc/passwd | grep -v root | cut -f1 -d ":"

列出系统中普通用户的用户名

 

 

 

9.2.4 awk命令

A:语法格式:awk '条件1{动作1}条件2{动作2}...' 文件

条件,一般使用关系表达式作为条件,如a>10。

动作,awk一次读入一整行,默认以tab键或者空格为分隔符将一行分为多个字段,

表示为$1、$2、$3...其中$0表示文件名

例:

打印文件的第二列,其中的转义字符要加双引号。

awk '{printf $2 "\n"}' /etc/passwd

显示某分区磁盘使用量百分比

df -h | grep "/dev/sda1" | awk '{print $5}' | cut -d "%" -f1

 

B:BEGIN、END作为关系表达式,表示命令执行开始时和结束时

例:

开始执行时FS指定分隔符

awk 'BEGIN{print "itpux:" }{print $1}' /etc/passwd

结束时打印一句话

awk 'END{print "itpux:"}{print $2}' /etc/passwd

 

9.2.5 sed命令

sed命令主要用来将数据进行选取、替换、删除、新增的命令

sed [选项] '动作' 文件名

选项:

-n:只会将sed处理的行输出,否则默认全篇输出

-e:允许进行多个动作

-i:sed修改默认是临时修改,

-i选项表示直接修改文件动作:

a:追加,在当前行后添加

c:行替换

i:在当前行前插入

d:删除指定行

p:打印输出指定行

s:字符串替换,格式:行范围s/旧字符串/新字符串/g

 

sed -n '2p' /etc/passwd 打印输出第二行

sed -i '2,4d' /etc/passwd 删除2至4行

sed -i '2a ok' /etc/passwd 第二行追加内容

sed -i '3c ok' /etc/passwd 替换第3行

sed -i '3i ok' /etc/passwd 在第3行前插入

sed -i '2s/spool/spool2/g' /etc/passwd 第2行的spool替换为spool2

sed -ie 's/var/var2/g;s/sbin/sbin2/g' /etc/passwd 同时多个动作

 

9.2.6 sort命令

01、sort命令用来排序

sort [选项] 文件名

选项:

-f:忽略大小写

-n:以数值型进行排序,默认是字符串排序

-r:反向排序

-t:指定分隔符,默认分隔符是tab键

-k n[,m]:指定排序的字段范围,n字段开始,m字段结束(可选),默认是到结尾

例:sort /etc/passwd 按首字母排序

9.3 Linux Shell条件判断与流程控制

9.3.1 test条件判断

格式:test [选项] file 或者 [(空格)条件判断式(空格)]

01、按文件类型进行判断

选项:

-d:判断文件是否存在,且是目录文件时为真

-e:判断文件是否存在,存在时为真

-f:判断文件是否为真,且为普通文件时为真

-b:判断文件是否存在,且为块设备文件时为真

-c:判断文件是否存在,且为字符设备时为真

-L:判断文件是否存在,且为符号链接文件时为真

-p:判断文件是否存在,且为管道文件时为真

-s:判断文件是否为非空,非空时为真

-S:判断套接字文件是否存在,存在时为真

例: [-e filename] && echo yes || echo no

 

02、按文件权限进行判断

-r:拥有读权限时为真

-w:拥有写权限时为真

-x:拥有执行权限时为真

 

03、两个文件间比较

文件1 -nt 文件2 判断文件1是否比文件2新,若新则为真

文件1 -ot 文件2 判断文件1是否比文件2旧,若旧则为真

文件1 -ef 文件2 判断文件1iNode节点号是否和文件2相同,(可用此判断硬链接)风

 

04、两个整数间比较

整数1 -eq 整数2 判断是否相等

整数1 -ne 整数2 判断是否不相等

整数1 -gt 整数2 判断是否大于

整数1 -ge 整数2 判断是否大于等于

整数1 -lt 整数2 判断是否小于

整数1 -le 整数2 判断是否小于等于

 

05、字符串的判断

-z 字符串 判断字符串是否为空

-n 字符串 判断字符串是否为非空

字符串1 == 字符串2 判断是否相等

字符串1 != 字符串2 判断是否不等

例:[ -z "$name"] $$ echo yes || echo no

 

 

06、多重条件判断

判断1 -a 判断2 逻辑与,1和2都为真最终结果才为真

判断1 -o 判断2 逻辑或,1和2有一个为真结果就为真

!判断 逻辑非

 

07、举例:两种判断格式:

test -e /root/install.log

[ -d /root ] && echo “yes” || echo “no”

第一个判断命令如果正确执行,则打印“yes”,否则打印“no”

注意Linux中0表示命令成功;1,表示命令失败。

例子:

[root@localhost ~]# ls install.log …

[root@localhost ~]# test -e /root/install.log

[root@localhost ~]# echo $?

0[r

oot@localhost ~]# test -e /root/install.log1

[root@localhost ~]# echo $?

1[r

oot@localhost ~]# test -e /root/install.log && echo yes || echo no

yes

[root@localhost ~]# test -e /root/install.log1 && echo yes || echo no

no

其实上面是if的单分支语句,注注意顺序不可以变化,如果no执行了那么yes也会出现,

毕竟正确执行了

9.3.2 流程控制

If语句:提供条件测试。测试可以基于各种条件。例如文件的权限、长度、数值或字符

串的比较。这些测试返回值或者为真(0),或者为假(1)。基于此结果,可以进行相

关操作。在讲到条件测试时已经涉及了一些测试语法。

01、单分支if语句

if [ 条件判断式 ]; then

程序

fi

或者:

if [ 条件判断式 ]

then

程序

fi

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

01:单if语句

#!/bin/bash

if [ "$USER" == root ];then

echo "Login User is root"

fi

#########或者#########

#!/bin/bash

if [ "$USER" == root ]

then

echo "Login User is root"

fi

 

02:双分支if语句

if [ 条件判断式 ]; then

条件成立时,执行的程序

else

条件不成立时,执行的程序

fi

或者:

if [ 条件判断式 ]

then

条件成立时,执行的程序

else

条件不成立时,执行的程序

fi

例1:输入一个文件,判断是否存在

#!/bin/bash

read -p "Please input a file:" file

if [ -f $file ]; then

echo "File: $file exists!"

else

echo "File: $file not exists!"

fi

 

 

03:多分支if语句

if [ 条件判断式1 ]; then

当条件判断式1成立时,执行程序1

elif [ 条件判断式2 ]; then

当条件判断式2成立时,执行程序2

.....省略更多条件.....

else

当所有条件都不成立时,最后执行此程序

Fi

 

 

04、多分支case语句

case允许匹配模式、单词或值。一旦模式或值匹

配,就可以基这个匹配条件作其他声明。

case语句和if...elif...else语句都是多分支条件语句,

不过和if多分支条件语句不同的是,

case语句只能判断一种条件关系,

而if语句可以判断多种条件关系。

 

 

case $变量名 in

"值1")

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

;;

"值2")

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

;;

.....省略其他分支.....

*)

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

;;

esac

 

例如:判断用户输入

#!/bin/bash

read -p "Please choose yes/no:" cmd

case $cmd in

"yes")

echo "Your choose is yes!"

;;

"no")

echo "Your choose is no!"

;;

*)

echo "Your choose is error!"

;;

9.3.3 循环

1 for循环

每次处理依次列表内信息,直至循环耗尽。

语法一:

for 变量名 in 值1 值2 值3 ...

do

程序

Done

语法二:

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

do

程序

Done

 

1加到1000

#!/bin/bash

s=0

for ((i=1;i<=1000;i=i+1))

do

s=$(($s+$i))

done

echo "$s"

 

echo "-----add 9 users-----"

for i in {1..9}; do

username=itpux0$i

if useradd $username &> /dev/null; then

echo "$username"|passwd --stdin $username

if [ $? -eq 0 ]; then

echo "add $username successful"

else

echo "$username added, change password failure "

fi

else

echo "add $username failure "

fi

done

 

2 while循环

while循环当条件为真时,循环执行。

流控制语句的任何循环均可嵌套使用,例如可以在一个for循环中嵌入另一个for

循环。

语法:

while [ 条件判断式 ]

do

程序

Done

 

#!/bin/bash

#a

wk -F: '{print $1,$3,$7}' /etc/passwd >>passwd.txt

while read name id shell

do

echo "user name:$name"

echo "user uid :$id"

echo "user shell:$shell"

echo

done < passwd.txt

 

3 until循环

until循环直至条件为真,条件部分在循环末尾部分。

语法: 是在条件不成立时执行

until [ 条件判断式 ]

do

程序

Done

 

 

#!/bin/bash

echo "This example is for test....do "

echo "If you input [exit] then quit the system "

echo -n "please input:"

read EXIT

until [ $EXIT = "exit" ]

do

read EXIT

done

echo "OK!

9.3.4循环控制语句

break 命令 不执行当前循环体内break下面的语句,从当前循环退出.

continue 命令是程序在本循体内忽略下面的语句,从循环头开始执行

 

脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使

用break命令。

#!/bin/bash

while :

do

echo -n "Input a number between 1 to 5: "

read aNum

case $aNum in

1|2|3|4|5) echo "Your number is $aNum"

;;

*) echo "You do not select a number between 1 to 5, game is over!"

break

;;

esac

done

 

 

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

#!/bin/bash

while :

do

echo -n "Input a number between 1 to 5: "

read aNum

case $aNum in

1|2|3|4|5) echo "Your number is $aNum!"

;;

*) echo "You do not select a number between 1 to 5!"

continue

echo "Game is over!"

;;

esac

done

发布了37 篇原创文章 · 获赞 0 · 访问量 2405

猜你喜欢

转载自blog.csdn.net/syjhct/article/details/100178593
今日推荐