分类: LINUX
2018-04-01 14:17:08
原文地址:沈超Shell编程笔记 作者:caoxwei
沈超:
微博:weibo.com/lampsc
shell编程(一)
一 shell简介
1 概念
命令解释器
2 常见shell bash
linux标准shell sh 早期shell,较简单
csh ksh tcsh unix shell
vi /etc/shells linux支持的shell
3 shell脚本
例1:打印时间 #!/bin/bash
echo "hello world!"
脚本执行方式: 1) 赋予执行权限
路径执行 /root/shell/echo.sh ./echo.sh
2) bash 脚本名 脚本可以不赋予执行权限
4 .bash常见功能
1)历史命令
默认保存1000条历史命令
vi /etc/profile 修改环境变量配置文件,要生效,必须注销
HISTSIZE=1000 修改默认历史命令条数
history 查询系统历史命令
历史命令保存文件 ~/.bash_history
history -w 把内存中命令历史,保存入文件 history -c 清空所
有的历史命令
重复历史命令
!n 重复第n条命令
!str 重复最后一个以str开头的命令 上箭头 调用上面的命令
2)别名 alias
查看系统中生效的别名
alias ls='ls --color=never' 手工设定别名,临时生效
vi ~/.bashrc 写入别名,永久生效
5 输入输出重定向
标准输入 /dev/stdin 0 键盘 标准输出
/dev/stdout 1 显示器 标准错误输出 /dev/stderr 2 显示器
#设备文件名 #文件描述符 #默认设备
1)输出重定向
把应该输出到屏幕的输出,重定向到文件。 > 覆盖 >> 追加
ls > aa
覆盖到aa ls >> aa
追加到aa
ls gdlslga 2>>aa
错误信息输出到aa
强调:错误输出,不能
有空格 ls &>aa 错误和正确都输入到aa,但是只能覆盖
掌握
ls >> aa 2>>bb
正确信息输入aa,错误信息输入bb ls >> aa 2>&1 错误和正确都输入
到aa,可以追加 2>&1 把标准错误重定向到标准正确输出
6 多命令顺序执行
1)命令1 ; 命令2 ; 命令3
命令123顺序执行。之间没有任何关
系
2)命令1 && 命令2 命令1正确执行后,命令2才会执行
)命令1 || 命令2 命令1执行不正确,命令2才会执行
ls aa && echo "cunzai" || echo "bu cunzai!" 执行ls aa,判断如果正确
,输出“存在”。如果不存在,输出“不存在”
7 管道符
命令1 | 命令2 命令1的执行结果,作为命令2的执行条件
netstat -tlun | grep 80 查询监听的端口号,并查看80端口是否启动。
ls -l /etc/ | more 分屏显示ls内容 ls -l /etc/ | grep yum 二 变量
1分类
本地变量 环境变量 位置参数变量 预定义变量
2本地变量
1)声明 变量名=变量值 注意:=号左右不能有空格 aa=123 2)调用
echo $变量名 3)查看变量
set 查看所有变量,包括环境变量和本地变量 4)删除
unset 变量名
3变量设定规则
1)变量以等号连接值,等号不能有空格
2)变量名由数字和字母和下划线组成,不能以数字开头 3)变量值中有空格,用引号括起来 4)双引号内,有特殊字符。如$ 5)单引号中特殊字符无含义 6)在变量值中,可以使用\转义符
7)变量值可以直接调用系统命令。 `命令` $(命令)
8)变量值可以累加 aa=123 aa="$aa"456 echo $aa --->123456
9)环境变量一定设为大写
4环境变量 1)声明
export 变量名=变量值 export aa
2)查看
set 查看所有变量
env export 只能查看环境变量
declare 声明变量类型的,如果不特别声明,所有变量为字符串型 -i 声明为int -x 声明为环境变量
3)删除
unset 变量名
4)常见环境变量 echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 系统查找命令的路径
PATH="$PATH":/root/shell 在系统默认路径后,追加/root/shell目录作为命令查找路径
5)环境变量配置文件 /etc/profile
/etc/bashrc 所有用户生效
~/.bashrc
~/.bash_profile 只对指定用户生效
shell编程(二)
二、变量
5.位置参数变量
$0 命令自己
$1 第一个参数
$2 第二个参数
$9 第九个参数
例子2:输出位置参数变量,脚本后要接参数
#!/bin/bash
Echo “the command is $0”
Echo “para 1 is $1”
6.预定义变量
$? 上一个命令的返回值 (0正确非零错误)
$#统计命令参数个数
$*返回所有参数
$n 位置参数变量
例子3:
Echo “para number is $#”
Echo “para list is $*”
Echo $?
7.键盘读取命令
Read –p “remind info” –t 等待时间 变量名
例子4:
#!/bin/bash
Read –p “please input num1” –t 30 num1
Read -p “please input num2 ” –t 30 num2
Sum = $(($num1+$num2))
8.数值运算
变量默认是字符串型,要想进行数值运算,以下三种任选一种
(1) declare方法
num1=123
num2=456
declare –i sum=$sum1+$sum2
(2)sum=$(($sum1 +$sum2))
(3)sum=$(expr $sum1 +$sum2)(+左边必须加空格)
(4)运算符 +-*/ %取余
三、shell中常用命令
1.行提取命令grep(-v 反向选择,-n 提取时显示行号)
举例:grep “{^a-z}hen” test.txt
Grep “\.$” test.txt
匹配以.结尾的行
Grep “^[^A-Za-z]” test.txt
匹配不以字母开头的行
Grep “$” test.txt
匹配空白行
Grep “oo*”test.txt
匹配最少一个o
2.列提取命令
(1)cut
Cut –d “分隔符” –f 提取列 文件名
More /etc/passwd |grep “/bin/bash”|cut –d “:” –f 1,3
(2) awk
awk ‘条件 {动作}’
last |awk ‘{printf $1 “\t”$3 “\n”}’
提取last 显示结果的第一和第三列
\t tab
\n 换行
\r回车
Last|grep“[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3}”
|awk ‘{printf $1 “\t” $3 “\n”}’
在last 中提取包含ip的行,从中提取1,3列
Awk 内置变量 FS指定分隔符
More /etc/passwd |awk ‘BEGIN {FS=”:”} {printf $1 “\t”$3 “\n”};’
以“:”为分隔符提取1,3 列
BEGIN 在截取前时分隔符生效,如果没有BEGIN ,那么第一行自定义分隔符不生效。
6 echo命令
Echo –e “输出内容”
-e 识别格式化打印内容
Echo –e “1\t\2\t3” 打印tab键
Echo –e “\e[1;31m this is red text \e[0m”
输出红色字体 \e[格式
1;31m指定颜色
0m:恢复颜色(重置)
30M=黑色 31m=红色 ,32m=绿色 33黄34 蓝35洋红36青 37白色(40 -47对应背景颜色)
Echo –e “\e[1:42 back ground \e[0m”
例子5:echo 输出的小游戏
取消dos文档回车符的两个方法
(1) dos2unxi 文档名
(2) vi –b 文档
:%s/^M/g ^M使用ctrl+v+m 输入
例子6:数据备份
#! /bin/bash
DAY =$(date+%F) #定义日期变量
SIZE=`du-sh /var/lib/mysql`#定义目录大小的变量
Echo “Date:$DAY”>> /tmp/dbinfo.txt
Cd /opt/dbbak
Tar zcf mysqlbak-${DAY}.tar.gz /var/lib/mysql /tmp/dbinfo.txt
Rm –f /tmp/dbinfo.txt
shell编程(三)
四 条件测试
Test 测试条件 测试内容
1. 测试文件类型
test –efdbc 文件名
-e 测试文件是否存在
-f 是否为普通文件
-d 是否为目录
-b 是否为块设备文件
-c 字符设备文件
2.测试文件权限
Test -rwxs 文件名
-r 是否可读
-w 是否可写
-x 是否可执行
-s 是否为非空,有内容则为真
3.两个文档比较
[file 1 -nt file2] file1是否比file2 新
[file1 -ot file2] file1是否比file2 旧
[file1 -ef file2] file1与file2是否是链接文件
4.两个数值判断
[n1 -eq n2 ] n1和n2是否相等
[n1 -ne n2 ] n1和n2是否不相等
[n1 -gt n2 ] n1大于n2
[n1 -lt n2 ] n1小于n2
[n1 -ge n2 ] n1大于等于n2
[n1 -le n2 ] n1小于等于n2
5.判断字符串
[-z 字符串] 字符串是否为空
[串1 = 串2] 是否相等
[串1 = 串2] 是否不相等
6.多重判断
-a 逻辑与
-o 逻辑或
! 逻辑非
例7:判断文件类型和文件权限
#!/bin/bash
Echo –e “does your file exist?what’s the access?\n\n”
Read –p “please input filename:” –t 30 filename
Test –z $filename && echo “please input filename!!”&&exit 1
#-z 变量 判断文件是否存在,存在为真 !逻辑非
Test ! –e $filename && echo “file doesn’t exit!”&&exit 2
Test –f $filename &&filetype=normal
Test –d $filename &&filetype=direcoty
Test –r $filename &&perm=“read”
Test –w $filename &&perm=”$perm write”
Test –x $filename &&perm=”$perm executable”
Echo –e “the filename is:$filename\n”
Echo –e “the filetype is:$filetype\n”
Echo –e “the permision is:$perm\n”
五、流程控制
1.if语句
(1)if条件语句—单分支
if 条件
then 命令
fi
例子8:
#!/bin/bash
RATE=`df –hT|grep “/boot”|awk ‘{print $6}’|cut –d “%d” –f1`
if[$RATE –gt 80]
Then “warning,/boot DISK if full!”
fi
2)if 双分支
if 条件
Then 命令1
Else 命令2
fi
例子9:
判断http服务是否启动,没有则启动
#!/bin/bash
http=`netstat –tlum|awk ‘{print $4 “\n”}’|grep”:80$”`
(或http = $(ps aux|grep httpd|grep –v grep))
if [-z “$http”]
Then
Echo “httpd is not start”
/etc/rc.d/init.d/httpd start
Else
Echo “httpd running”
fi
(3)if 多分支
if 条件1:
Then 命令1
elif 条件2:
Then 命令2
elif
else
命令序列n
fi
例子10:
#!/bin/bash
Echo “if you want to Beijing,please input 1”
Echo “if you want to shanghai,please input 2”
Echo “if you want to chengdu,please input 3”
Read –p “please input :” –t 30 num
if [“$num”== “1”]
Then echo “beijng!!”
elif[“$num”== “2”]
Then ehco “shanghai”
elif[“$num”== “3”]
Then ehco “chengdu”
else
Echo “error ,please input 1 or 2 or 3”
fi
shell编程(四)
五 流程控制
2 for语句
1) 使用in关键字循环
根据变量的不同取值,重复执行一组命令操作
格式:
for 变量名 in 取值列表
do
命令序列
done
例子11:循环
#!/bin/bash
for time in morning noon afternoon evening
do
echo $time
done
例子12:
#输入目录名,显示目录下所有内容.
#!/bin/bash
read -p "please input a filename!" -t 30 filename
if [ -z $filename ];then
echo "please input!!!!!!"
exit 1
fi
#如果字符串为空,报错跳出
if [ ! -e $filename ]
then
echo "$filename not cunzai!!"
exit 2
fi
#如果文件不存在,报错跳出
if [ ! -d $filename ]
then
echo "$filename is not driectory"
exit 3
fi
#如果不是目录,报错跳出
file=`ls $filename`
for test in $file
do
echo $test
done
2)数值加加循环
例子13:
#/bin/bash
s=0
for ((i=1;i<=100;i=i+1))
do
s=$(($s+$i))
done
echo $s
3 while循环语句
重复测试指定的条件,只要条件成立则反复执行对应的命令操作
格式:
while 命令或表达式
do
命令列表
done
例子14:
批量添加用户
#!/bin/bash
i=1
while [ $i -le 20 ]
do
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/null
i=`expr $i + 1`
done
例子15:
批量删除用户
#!/bin/bash
aa=`cat /etc/passwd | grep "/bin/bash"|grep -v "root"|cut -d ":" -f 1`
for i in $aa
do
userdel -r $i
done
例子16:
批量添加
#!/bin/bash
aa=10
for ((i=1;i<=$aa;i=i+1))
do
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/null
echo $i
done
4 case多重分支语句
根据变量的不同取值,分别执行不同的命令操作
例子17:
打印选择列表,输出选择
#!/bin/bash
echo -e "shanghai: 1\n"
echo -e "beijing: 2\n"
echo -e "chengdu: 3\n"
read -p "input your choice:" -t 30 choi
case $choi in
"1")
echo "shanghai!!!"
;;
"2")
echo "beijing!!!"
;;
"3")
echo "chengdu!!!"
;;
*)
echo "qing chongxin shuru!"
;;
esac
六 apache启动脚本分析:
#!/bin/bash
#
# httpd Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
#自启动设定 -代表自启动级别,85(S85)代表启动序号,15(K15)代表关闭序号。
# description: The Apache HTTP Server is an efficient and extensible \
# server implementing the current HTTP standards.
#服务描述。以上两行用于apache自启动。
# processname: httpd
# config: /etc/httpd/conf/httpd.conf
# config: /etc/sysconfig/httpd
# pidfile: /var/run/httpd/httpd.pid
#
### BEGIN INIT INFO
# Provides: httpd
# Required-Start: $local_fs $remote_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Should-Start: distcache
# Short-Description: start and stop Apache HTTP Server
# Description: The Apache HTTP Server is an extensible server
# implementing the current HTTP standards.
### END INIT INFO
#以上都是注释。
# Source function library.
. /etc/rc.d/init.d/functions
#"."其实就是source,就是调用functions文件。
if [ -f /etc/sysconfig/httpd ]; then
. /etc/sysconfig/httpd
fi
#判断httpd如果是文件,则调用httpd文件。
# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}
#定义变量HTTPD_LANG的值。并追加变量的值为C,即英文。
# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""
# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.
# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/sbin/apachectl
httpd=${HTTPD-/usr/sbin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
#定义一系列变量,用于后面的执行。
RETVAL=0
#定义全局命令返回变量。
STOP_TIMEOUT=${STOP_TIMEOUT-10}
# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure. So we just do it the way init scripts
# are expected to behave here.
start() {
echo -n $"Starting $prog: "
LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${lockfile}
return $RETVAL
}
#定义start函数,用于apache的启动。
#如果守护进程/usr/sbin/httpd 启动成功($RETVAL
= 0),就建立/var/lock/subsys/httpd文件(touch #${lockfile})。通过$httpd变量执行/usr/sbin/httpd命令启动apache。通过$pidfile变量调用apache
#的PID。通过变量$OPTIONS定义命令执行时的初始化环境配置,依赖/etc/sysconfig/httpd文件。
# When stopping httpd, a delay (of default 10 second) is required
# before SIGKILLing the httpd parent; this gives enough time for the
# httpd parent to SIGKILL any errant children.
stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} -d ${STOP_TIMEOUT} $httpd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
#定义stop函数,用来关闭apache服务,关闭服务之后会删除pid文件。
reload() {
echo -n $"Reloading $prog: "
if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
RETVAL=6
echo $"not reloading due to configuration syntax error"
failure $"not reloading $httpd due to configuration syntax error"
else
# Force LSB behaviour from killproc
LSB=1 killproc -p ${pidfile} $httpd -HUP
RETVAL=$?
if [ $RETVAL -eq 7 ]; then
failure $"httpd shutdown"
fi
fi
echo
}
#定义reload函数,用于apache的重新加载。
#通过/usr/sbin/httpd –t命令判断apache的配置文件。如果配置文件报错,则输出错误提示。如果配
#置文件正确,则重新加载apache。
# See how we were called.
case "$1" in
#判断执行脚本后的第一个参数的值,$1表示执行脚本时的第一个参数。
start)
start
;;
;;
#如果参数值为start,则调用start函数。
stop)
stop
;;
#如果参数值为stop,则调用stop函数。
status)
status -p ${pidfile} $httpd
RETVAL=$?
;;
#如果参数值为status,则执行status –p $httpd命令测试apache状态。
restart)
stop
start
;;
#如果参数值为restart,则先调用stop函数,再调用start函数
condrestart|try-restart)
if status -p ${pidfile} $httpd >&/dev/null; then
stop
start
fi
;;
#如果参数值为condrestart或try-restart,则只有apache服务是已经运行时才先调用stop函数,再调
#用start函数,重启apache。如果apache服务没有运行,则不重启apache。
force-reload|reload)
reload
;;
#如果参数值为force-reload或reload,则调用reload函数。
graceful|help|configtest|fullstatus)
$apachectl $@
RETVAL=$?
;;
#如果参数是graceful或help或configtest或fullstatus,则执行/usr/sbin/apachectl命令,并把参
#数作为命令的参数传入apachectl命令。
*)
echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}"
RETVAL=2
#如果输出的参数不是以上任何参数,则输出错误信息
esac
exit $RETVAL