Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17890
  • 博文数量: 17
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 186
  • 用 户 组: 普通用户
  • 注册时间: 2023-06-22 08:56
文章分类

全部博文(17)

文章存档

2023年(17)

我的朋友

分类: LINUX

2023-06-22 10:33:16

18.Linux Shell编程基础与Shell环境
1.Linux Shell编程基础 
2.Linux Shell变量
3.Linux Shell正则表达式
4.Linux Shell条件判断与流程控制




  
笔记:


1.Linux Shell编程基础 
Shell是什么?


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


Shell是解释执行的语言,能直接调用Linux系统命令。可以说,
shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度。


Shell分类: Bourne Shell:sh、ksh、Bash、psh
   C   Shell:csh、tcsh
Shell有两种执行命令的方式:
交互式(Interactive)     
批处理(Batch)       


Shell初学者请注意,在平常应用中,建议不要用root账号运行shell。


Linux的echo命令,在shell编程中极为常用,在终端下打印变量value的时候也是常常
用到的。


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


shell别名:
alias 查看系统中已有的别名
alias ls='ls -lsa' 
设置别名,要永久生效需将该命令放入~/.bashrc文件或~/.bash_profile中


unalias  ls   删除别名


Bash shell中常用快捷键:
ctrl+c 强制终止
ctrl+l 清屏
ctrl+u 从光标位置删到行首
ctrl+a 从光标位置移到行首
ctrl+e 从光标位置移到行尾
ctrl+z 命令放到后台


shell多命令执行:
命令1;命令2 分号;表示多个命令顺序执行
命令1&&命令2    逻辑与,命令1执行正确则执行命令2,命令1执行错误则
不执行2
命令1||命令2    逻辑或,命令1执行正确则不执行2,命令1执行不正确则
执行命令2

SHELL重定向:
01.标准输出重定向
命令 > 文件 覆盖的方式写入
命令 >> 文件 追加的方式写入
02.标准错误输出重定向
错误命令 2> 文件
错误命令 2>> 文件  (注意:2和>之间无空格) 
03.正确和错误信息同时重定向
命令 > 文件 2 > &1
命令 >> 文件 2 > &1
命令 &> 文件 
命令 >> 文件 1 2>>文件2 正确和错误信息分开保存
ls -lsa > /dev/null
不想要的打印信息全部重定向到/dev/null下,输入到此的文件全被系统丢掉。
04.输入重定向
wc < 1.log 统计文件中的行数、单词书、字节数


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的进程,并统计行数






Shell通配符:
? 匹配任意一个字符
* 匹配任意内容
[] 匹配括号内任意一个字符
[0-9] -表示范围,匹配其中一个
[^0-9] 逻辑非^,匹配非括号内内容


Bash中其它符号:
$ 调用变量的值
\ 转义符,跟在\之后的特殊符号将失去特殊含义,如\*就是输出*号
# Shell中表示注释
$() 用来引用系统命令


Shell历史命令:
Bash的历史命令保存在~/.bash history里


history 命令显示历史命令
history -c  清空历史命令
history -w  将本次开机以来的命令写入历史命令文件


SHELL简单的执行跟踪:
set -x命令打开跟踪功能,在此之后shell会显示每条被执行的命令,前面附带+号
set +x 关闭跟踪功能
例如:
#! /bin/bash
set -x
echo 1 itpux
set +x
echo 2 itpux
执行结果:
+echo 1 itpux
+set +x
echo 2 itpux


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
 










2.Linux Shell变量
Bash Shell变量主要分为4种:
用户自定义变量、环境变量、位置变量、预定义变量。 


本文主要介绍这4种变量:
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}
$*  代表命令行中所有参数,$*把所有参数当做一个整体
$@  代表命令行所有参数,$@把每个参数区分对待
$# 代表命令行中参数的个数


$? {BANNED}最佳后一次执行的命令的返回状态。若为0,则表示命令执行正确;若为非0,代表上一条
指令执行错误。
$$ 当前进程的进程ID号
$! 后台运行的{BANNED}最佳后一个进程的进程号




4、环境变量配置文件
4.1 source命令  修改配置文件后使之生效
source 配置文件
或者 .配置文件
如:source /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
不管是本地还是远程登录都能显示此信息。






3.Linux Shell正则表达式
正则表达式的介绍:
正则表达式是描述字符排列和匹配模式的一种语法规则。
正则表达式主要用于字符串的模式分割、匹配、查找及替换。
正则表达式主要为了模糊匹配。


正则表达式与通配符区别:
01.通配符(* ? [])用来匹配符合条件的文件名,是完全匹配。
ls、find、cp这些命令不支持正则表达式,支持通配符匹配。
02.正则表达式用来匹配在文件中的字符串,是包含匹配。
grep、awk、sed等命令支持正则表达式。


基础正则表达式:
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{BANNED}最佳少出现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地址




字符截取命令:
01.cut命令:cut命令用于列提取,默认分隔符是tab键。


选项:-d 指定分隔符,-f 指定提取第几列
例:cut -d ":" -f1 /etc/passwd
为:为分隔符提取文件的{BANNED}中国第一列


grep "/bin/bash" /etc/passwd |grep -v root |cut -f1 -d ":"
列出系统中普通用户的用户名


02.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


C:格式化输出printf:
printf命令用于格式化输出,是echo命令的增强版
命令格式:printf '输出类型转义符' 输出内容


常用输出格式:
%ns:输出字符串;输出n位的字符串
%ni:输出整数:输出n位的整数
%m.nf:输出浮点数:m位整数和n位小数


print比printf更强的就是自动换行。


printf常用转义符:
\t 水平tab键 \v 垂直tab键 \n 换行 \r  回车,Enter键
\f 清除屏幕 \b 输出退格键 \a 输出警告声音


printf常用举例:


#printf %s abcdef
abcdef
#printf "%s\n" abc def
abc
def




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 同时多个动作




sort命令:
01.sort命令用来排序
sort [选项] 文件名
选项:
-f:忽略大小写
-n:以数值型进行排序,默认是字符串排序
-r:反向排序
-t:指定分隔符,默认分隔符是tab键
-k n[,m]:指定排序的字段范围,n字段开始,m字段结束(可选),默认是到结尾


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


wc命令:统计命令
wc [选项] 文件名
-l:只统计行数
-w:只统计单词数
-m:只统计字符数,包括换行符
例如: ps -ef|grep LOCAL=NO |wc -l


 










4.Linux Shell条件判断与流程控制
条件判断:
格式: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 都为真{BANNED}最佳终结果才为真
判断1 -o 判断2 逻辑或,1和2 有一个为真结果就为真
!判断1 逻辑非 


07.举例: 两种判断格式:
test -e /root/install.log 
[-d /root] && echo "yes" || echo "no"
{BANNED}中国第一个判断命令如果正确执行,则打印"yes",否则打印"no"
注意Linux中0表示命令成功; 1,表示命令失败


例子:
[root@localhost~]#ls install.log ...
[root@localhost~]#test -e /root/install.log
[root@localhost~]#echo $?
0
[root@localhost~]#test -e /root/install.log1
[root@localhost~]#echo $?
1
[root@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也会出现,
毕竟正确执行了




流程控制:
if语句:提供条件测试。测试可以基于各种。例如文件的权限、长度、数值或字符串的
比较。这些测试返回值或者为真(0),或者为假(1).基于此结果,可以进行相关
操作。在讲到条件测试时已经涉及了一些测试语法。


01.单分支if语句
if[条件判断式];then
程序
fi
或者
if[条件判断式]
then
程序
fi
注意:中括号和条件判断式之间必须有空格


例1:判断当前用户是root
#!/bin/bash 


if ["$USER"==root];then
echo "Login User is root"
fi


###################或者########################
#!/bin/bash


if ["$USER"==root]
then
echo "Login User is root"
fi


例2:判断分区空间使用率


#!/bin/bash 
test=$(df -h |grep /dev/sda1 |awk '{print $5}' |cut -d "%" -f1)
if [$test -ge 10]
then 
echo "sda1 is 10"
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




例2:判断apache服务是否启动了,如果没有启动,就代码启动
#!/bin/bash 


test=$(ps aux|grep httpd|grep -v 'grep'|wc -l)


if[$test -gt 0];then 
echo "$(date) httpd is running!"
  else 
    echo "$(date) httpd isn't running,will be started!"
/etc/init.d/httpd start 
fi 





03.多分支if语句


if [条件判断式1];then
当条件判断式1成立时,执行程序1
elif [条件判断式2];then 
当条件判断式2成立时,执行程序2
....省略更多条件....
else 
  当所有条件都不成立时,{BANNED}最佳后执行此程序
fi  




04.多分支case语句
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!"
;;
esac




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


语法一:
for 变量名 in 值1 值2 值3 ...
do
程序
Done


语法二:
for ((初始值;循环控制条件;变量变化))
do
程序
done


例1:批量解压缩文件


#!/bin/bash 
ls *.tar.gz > tar.log 
for i in $(cat tar.log)
do 
  tar -zxf $i &>/dev/null 
done 
rm -rf tar.log 

例2:1加到1000


#!/bin/bash
s=0
for((i=1;i<=1000;i=i+1))
do
s=$(($s+$i))
done
echo "$s"




例3:批量添加用户
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


例4:批量删除普通用户


#!/bin/bash 
for i in $(cat /etc/passwd |grep /bin/bash |grep -v root |cut -d ":" -f1)
do 
userdel $i 
done 



while循环:
while循环当条件为真时,循环执行。
流控制语句得任何循环均可嵌套使用,例如可以在一个for循环中嵌入另一个for循环。


语法:
while [条件判断式]
do 
程序
done


例:
#!/bin/bash 
#
awk -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文件的列数一定要大于变量的个数,否则,会报错




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


语法:是在条件不成立时执行
until [条件判断式]
do 
程序
done




案例:


vi 1.sh


#!/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!"


执行脚本:
chmod 775 1.sh
./1.sh 




循环控制语句:
break命令不执行当前循环体内break下面的语句,从当前循环退出。
continue命令是程序在本循环体内忽略下面的语句,从循环头开始执行。


例1:脚本进入死循环直至用户输入数字大于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    




例2: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,game is over!"
continue
echo "Game is over!"
;;
   esac
done    
 














































******************************************************************










阅读(8752) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~