您的位置:首页 > 运维架构 > Shell

bash代码

2015-07-25 19:12 585 查看
bash代码:
#!/bin/bash
MySQLSTARTUP="/data/3306/mysql"
DbProcessCount=`ps -ef|grep mysql|grep -v grep|wc -l`
DbPortCount=`netstat -lnt|grep 3306|wc -l`

if [ $DbProcessCount -eq 2 ] && [ $DbPortCount -eq 1 ]
then
echo "mysql is running! "
else
$MySQLSTARTUP start >/tmp/mysql.log
sleep 20;
if [ $DbProcessCount -ne 2 ] || [ $DbPortCount -ne 1 ]
then
killall mysqld >/dev/null 2>&1
sleep 5
killall mysqld >/dev/null 2>&1
sleep 5
[ $DbPortCount -eq 0 ] && $MySQLSTARTUP start >>/tmp/mysql.log
[ $? -eq 0 ] &&  echo "mysql is started"
fi
mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log
fi


2) 通过连接mysql 执行命令来判断

bash代码:
#!/bin/bash
MySQLSTARTUP="/data/3306/mysql"
mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1
if [ $? -eq 0 ]
then
echo "mysql is running! "
else
$MySQLSTARTUP start >/tmp/mysql.log
sleep 10;
mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1
if [ $? -ne 0 ]
then
killall mysqld  >/dev/null 2>&1
killall mysqld  >/dev/null 2>&1
sleep 10
$MySQLSTARTUP start >>/tmp/mysql.log
fi
mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log
fi


3) 较专业的写法:

bash代码:
#!/bin/bash
MYUSER=root
MYPASS=""
MYSOCK=/data/3306/mysql.sock
MySQL_STARTUP="/data/3306/mysql"
LOG_PATH=/tmp
LOG_FILE=${LOG_PATH}/mysqllogs_`date +%F`.log
MYSQL_PATH=/usr/local/mysql/bin
MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS -S $MYSOCK"

$MYSQL_CMD -e "select version();" >/dev/null 2>&1
if [ $? -eq 0 ]
then
echo "MySQL is running! "
exit 0
else
$MySQL_STARTUP start >$LOG_FILE
sleep 5;
$MYSQL_CMD -e "select version();" >/dev/null 2>&1
if [ $? -ne 0 ]
then
for num in `seq 5`
do
killall mysqld  >/dev/null 2>&1
[ $? -ne 0 ] && break;
sleep 1
done
$MySQL_STARTUP start >>$LOG_FILE
fi
$MYSQL_CMD -e "select version();" >/dev/null 2>&1 && Status="restarted" || Status="unknown"
mail -s "MySQL status is $Status" @qq.com < $LOG_FILE
fi
exit


例3 监控apache

1) 对端口、进程和url同时监测。

bash代码:
#!/bin/bash
. /etc/init.d/functions
LOG_FILE=/tmp/httpd.log
apachectl="/application/apache/bin/apachectl"
HTTPPORTNUM=`netstat -lnt|grep 80|grep -v grep|wc -l`
HTTPPRONUM=`ps -ef|grep http|grep -v grep|wc -l`
wget --quiet --spider http://10.0.0.179:8000 && RETVAL=$?
[ ! -f $LOG_FILE ] && touch $LOG_FILE
if [ "$RETVAL" != "0" -o "$HTTPPORTNUM" -lt "1"  -o  "$HTTPPRONUM" \< "1" ] ;then
action "httpd is not running" /bin/false
echo -e "httpd is not running\n" >$LOG_FILE
echo "Preparing start apache..."
for num in `seq 10`
do
killall httpd  >/dev/null 2>&1
[ $? -ne 0 ] && {
echo "httpd is killed" >$LOG_FILE
break;
}
sleep 2
done
$apachectl start >/dev/null 2>&1 && Status="started" || Status="unknown"
[ "$Status" = "started" ] && action "httpd is started" /bin/true||\
action "httpd is started" /bin/false
mail -s "`uname -n`'s httpd status is $Status" xx@qq.com <$LOG_FILE
exit
else
action "httpd is running" /bin/true
exit 0
fi


2) 使用nmap检测

bash代码:
#!/bin/bash
ip_add="$1"
port="$2"
print_usage(){
echo -e "$0 ip port"
exit 1
}

#judge para num
if [ $# -ne 2 ]
then
print_usage
fi
PORT_COUNT=`nmap $ip_add  -p $port|grep open|wc -l`
#echo -e "\n" |telnet $ip_add $port||grep Connected
#echo -e "\n"|telnet 10.0.0.179 8000|grep Connected
[[ $PORT_COUNT -ge 1 ]] && echo "$ip_add $port is ok." || echo "$ip_add $port is unknown."


No.001 文件安全与权限

1. umask 决定了新建文件的权限
2. 软链接(符号链接) ln -s source_path target_path

No.002 find和xargs

1. find pathname -options [-print -exec -ok]
其中exec参数的命令格式: 'command-' {} \; 注意必须包含【{} \;】
-perm 按权限来查找  ex. find . -perm 755 -print
-mtime 按修改时间来查找 ex. find / -mtime -5 -print 更改时间5天以内
find / -mtime +5 -print 更改时间5天以前
2. xargs与-exec和-ok类似,但是限制更少,也更快
3种参数的命令:find . -name "*.c" -exec wc -l {} \;
find . -name "*.c" -ok wc -l {} \;   每次执行命令前有提示
find . -name "*.c" | xargs wc -l

No.003 后台执行命令

1. [crontab] [at] [&] [nohup]四种

No.004 文件名置换

1. 列出隐藏文件 ex. ls .*

No.005 shell输入与输出

1. echo输出时加上 -n 参数不换行, ex. echo -n "aaaa"
2. tee 命令可以同时输出到屏幕和文件中 ex. ls | tee file.out
3. 标准输入 0  标准输出 1  标准错误 2
4. 将标准输出和标准错误输入到一个文件  ex. command >file.out 2>&1

No.006 命令执行顺序

1. 命令1 && 命令2    命令1执行成功后才会执行命令2
2. 命令1 || 命令2    命令1执行失败后才会执行命令2

No.007 正则表达式

1. 正则表达式元字符及含义
^                     只匹配行首
$                     只匹配行尾
*                     匹配0次或多次
[]                    匹配[]内字符
\                     转义符
.                     匹配任意一个字符
pattern\{n\}          匹配pattern出现的次数,n次
pattern\{n, \}        同上,最少n次
pattern\{n, m\}       同上,次数在n与m之间

No.008 grep

1. grep 主要选项及其含义
-c    只输出匹配行的行数
-i    不区分大小写
-h    查询多文件时不显示文件名
-l    查询多文件时只输出包含匹配字符的文件名
-n    显示匹配行及行号
-s    不显示不存在或无匹配文本的错误信息
-v    显示不包含匹配文本的所有行
2. 查询空行 grep '^$' filename
3. 类名及等价的正则表达式
[[:upper:]]    =    [A-Z]
[[:lower:]]    =    [a-z]
[[:digit:]]    =    [0-9]
[[:alnum:]]    =    [0-9a-zA-Z]
[[:space:]]    =    空格或tab键
[[:alpha:]]    =    [a-zA-Z]

No.009 AWK

# awk的主要作用在于将文本分成各个区域,便于分别进行处理
1. awk -F指定分隔符,-f指定awk脚本
ex. awk -F: 'commands' input-file(s)
ex. awk -f awk-script input-file(s)
2. awk 分隔出的域用$1,$2...$n来表示,其中$0表示所有域
3. awk 条件操作符 <, <=, >=, ==, !=
~  匹配正则表达式   !~  不匹配正则表达式
4. awk 内置变量
ARGC        命令行参数个数
ARGV        命令行参数排列
ENVIRON     支持队列中系统环境变量的使用
FILENAME    awk浏览的文件名
FNR         浏览文件的记录数
FS          设置输入域分隔符,等价于命令行-F选项
NF          记录的域个数
NR          已读的记录数
OFS         输出域分隔符
ORS         输出记录分隔符
RS          控制记录分隔符
ex. awk '{print NF,NR,$0} END{print FILENAME}' input-file
5. awk 字符串函数
gsub, index, length, match, split, sprint, sub, substr, substr
6. awk 中的printf函数可以控制格式化输出
7. awk 的循环结构 For (element in array) print array[element]

No.010 sed

# sed的主要作用在于过滤和查找文本中的特定内容
1. sed 命令格式: sed [options] sed-command input-file
sed [options] -f sed-script input-file

No.011 合并和分隔文件

1. sort, uniq, join, cut, paste, split

No.012 tr的用法

1. 去除oops.txt中的重复字符 tr -s "[a-z]" < oops.txt
2. 去除oops.txt中的空行 tr -s "[\n]" < oops.txt
3. oops.txt中小写转大写 tr -s "[a-z]" "[A-Z]" < oops.txt

No.013 登录环境

1. /etc/passwd 保存所有账号的基本信息(不包括密码)
2. /etc/profile 基本的配置信息,登录时读取此文件
3. $HOME/*profile 各个用户的profile文件,会覆盖系统的profile文件
4. $HOME/*logout logout(键入命令exit时)是执行的脚本

No.014 环境和shell变量

1. shell变量的设置方式
Variable-name=value    设置实际值到variable-name
Variable-name+value    如果设置了variable-name,则重设其值
Variable-name:?value   如果未设置variable-name,显示未定义用户错误信息
Variable-name?value    如果未设置variable-name,显示系统错误信息
Variable-name:=value   如果未设置variable-name,设置其值
Variable-name:-value   如果未设置variable-name,就用value,但是不设置variable-name
2. 设置只读变量  readonly variable-name
3. export variable-name 可以将变量导入到子shell中
4. shell脚本的参数 $0表示脚本名字,$1表示第一个参数......$9表示第九个参数
5. 特定shell变量
$#    参数个数
$*    用一个字符串显示所有参数
$$    脚本运行的当前进程ID
$!    后台运行的最后一个进程的进程ID
$@    与$*相同,每个参数作为独立的字符串
$-    显示shell的当前选项,与set命令相同
$?    显示shell命令的退出状态,0表示无错误,其他表示有错

No.015 引号

1. 双引号("") 其中引用的变量会替换为变量值。比如:
[wangyb@localhost bash]$ STR="Hello world"
[wangyb@localhost bash]$ echo "$STR"
Hello world
2. 单引号('') 忽略变量和其他特殊字符,单引号内任何内容都当成字符串显示。比如:
[wangyb@localhost bash]$ STR="Hello world"
[wangyb@localhost bash]$ echo '$STR'
$STR
3. 单引号和双引号同时使用时,谁在外面谁起作用。比如
[wangyb@localhost bash]$ echo "'$STR'"
'Hello world'
[wangyb@localhost bash]$ echo '"$STR"'
"$STR"
4. 反引号(``) 反引号中的内容被当做命令来执行。比如
[wangyb@localhost bash]$ VAR=`date`
[wangyb@localhos bash]$ echo $VAR
Thu Dec 22 22:08:07 JST 2011
5. 转义符(\)

No.016 Shell脚本介绍

1. 脚本的第一行一般以  #!/bin/bash  开始
2. 给脚本加入执行权限后就可以运行脚本了

#No.017 条件测试

1. 测试语法  test condition 或者 [ condition ] 使用方括号是注意在condition两边加上空格
2. 文件状态测试
-d    目录            -s    文件长度大于0
-f    正规文件        -w    可写
-L    符号连接        -u    文件有suid位设置
-r    可读            -x    可执行
例子如下:测试是否为目录,也可以用 test -d bash.sh 来代替方括号
[root@localhost bash]# [ -d bash.sh ]
[root@localhost bash]# echo $?
1
[root@localhost bash]# [ -d . ]
[root@localhost bash]# echo $?
0
3. 逻辑与 -a  逻辑或 -o  逻辑否 ! 例子如下:
[root@localhost bash]# [ -d bash.sh -a -d . ]
[root@localhost bash]# echo $?
1
[root@localhost bash]# [ -d bash.sh -o -d . ]
[root@localhost bash]# echo $?
0
[root@localhost bash]# [ ! -d bash.sh -a -d . ]
[root@localhost bash]# echo $?
0
[root@localhost bash]# [ ! -d bash.sh -a ! -d . ]
[root@localhost bash]# echo $?
1
4. 字符串测试  [ string1 string_operator string2 ] 或者 [ string_operator string ]
string_operator可为:=      两个字符串相等
!=     两个字符串不等
-z     空串
-n     非空串
5. 数值测试  [ "number1" num_operator "number2" ]
num_operator可为:  -eq     数值相等
-ne     数值不等
-gt     number1 > number2
-lt     number1 < number2
-le     number1 <= number2
-ge     number1 >= number2
例子:   [root@localhost bash]# [ "100" -gt "101" ]
[root@localhost bash]# echo $?
1
[root@localhost bash]# [ "100" -lt "101" ]
[root@localhost bash]# echo $?
0
6. expr语法  expr arg1 operator arg2
例子:变量自增
[root@localhost bash]# COUNT=1
[root@localhost bash]# echo $COUNT
1
[root@localhost bash]# COUNT=`expr $COUNT + 1`
[root@localhost bash]# echo $COUNT
2

No.018 控制流结构

1. if语句格式
if 条件1
then
执行命令1
elif 条件2
then
执行命令2
else
执行命令3
fi
2. case语句格式
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
......
easc
其中的“模式”可以是 *(任意字符), ?(任意单字符), [..](范围内任意字符)
“模式”中还可以是使用 | (比如 str1|str2 表示str1和str2都可以)
3. for语句格式
for 变量名 in 列表
do
命令1
命令2 ......
done
4. until语句格式
until 条件
命令1
......
done
一直执行至条件为真时才结束,至少执行一次
5. while语句格式
while 条件
命令1
......
done
6. 利用IFS来改变读取内容的分隔符
7. 利用break和continue控制循环的执行

No.019 Shell函数

1. shell函数格式
函数名 ()
{
命令1
......
}
或者
function 函数名 ()
{
命令1
......
}
2. 引用其他脚本中函数  . /pathname/funcfile (<点><空格><斜线><文件完整路径名>或者<点><空格><文件相对路径名>)
3. 函数中通过 $1, $2,......$9来获取参数

No.020 向脚本传递参数

1. 使用shift依次获取各个参数,比如
while [ $# -ne 0 ]
do
echo $1  # 通过shift,$1将依次表示各个参数
shift
done
2. getopts语法格式 getopts operation-string variable。

No.021 屏幕输出

1. tput 控制屏幕上的字符输出,比如加粗字符,隐藏光标等等
2. 改变字符颜色的方法,比如
echo "<CTRL-V><ESCAPE>[40;32m"   设置背景黑色(40), 字符绿色(32)

No.022 屏幕输入

1. 输入时进行validation check
“送进的是垃圾,出来的肯定是垃圾”

No.023 调试脚本

1. shell不会对错误进行精确定位,当shell打印错误后,需要观察报错的整个代码段
2. 在脚本中利用set命令辅助调试
set -n    读命令但不执行
set -v    显示读取的所有行
set -x    显示所有命令及参数
- 表示打开; + 表示关闭;set +x 表示关闭显示所有命令及参数

No.024 shell 嵌入命令

1. set 命令在脚本中设置脚本的运行参数
2. times命令打印shell消耗时间和运行命令消耗时间 ???
3. type 命令查询命令是否有效及命令类型
4. ulimit 命令设置运行在shell上的显示限制
5. wait 命令是父进程等待子进程完成

No.025 深入讨论<<

1. 创建文本  ex. cat >> file <<end
> (输入内容)
> end
(输入内容)将被追加到file中

No.026 shell工具

1. 用日期做文件名,ex.  $ Myfile=`date +%Y%m%d%H%M%S`
$ touch $Myfile
2. 脚本中的临时文件名中加入进程号,可以保证文件名唯一,并在脚本结束时删掉文件
ex. TmpFile1=/tmp/tempfile1.$$
TmpFile2=/tmp/tempfile2.$$
rm /tmp/*.$$
3. 常用信号
信号    信号名        含义
1       SIGHUP        挂起或父进程被杀死
2       SIGINT        来自键盘的中断信号,通常是<CTRL-C>
3       SIGQUIT       从键盘退出
9       SIGKILL       无条件终止
11      SIGSEGV       段(内存)冲突
15      SIGTERM       软件终止(缺省杀进程信号)
4. trap 捕获信号 语法 trap "do-something" signal(s)
ex.  trap "" 2 3           忽略信号2和信号3,用户不能终止该脚本
trap "commands" 2 3   如果捕捉到信号2和信号3,就执行相应的commands
trap 2 3              复位信号2和3,用户可以终止该脚本
5. eval 对变量进行2次扫描 比如:
[wangyb@localhost bash]$ VAR1="cat a.sh"
[wangyb@localhost bash]$ echo $VAR1
cat a.sh
[wangyb@localhost bash]$ eval echo $VAR1
cat a.sh
[wangyb@localhost bash]$ eval $VAR1
#!/bin/bash
TMP='HELLO'
sleep 2
times
6. 获取命令行的最后一个参数: ex. $(eval echo \$$#)
7. logger 命令记录日志

No.027 几个脚本例子

# 作者常用的几个脚本
No.028 运行级别脚本

1. 确定当前的运行级别:who -r
2. 运行级别含义
运行级别0    启动和停止整个系统
运行级别1    单用户或管理模式
运行级别2    多用户模式;部分网络服务被启动。
运行级别3    正常操作运行模式,启动所有的网络服务
运行级别4    用户定义的模式,可以使用该级别来定制所需要运行的服务
运行级别5    有些Unix操作系统变体叫起作为缺省X-windows模式
运行级别6    重启动

No.029 cgi脚本
# 感觉现在应该不会有人用bash来开发web程序了吧
No.030 常用shell命令
1. basename : basename path
2. cat : cat optiones file
-v 显示控制字符
3. compress : compress options files
-v 显示压缩结果
4. cp : cp options file1 file2
-i 覆盖文件之前提示用户确认
-p 保留权限模式和更改时间
-r 拷贝相应的目录及其子目录
5. diff : diff options file1 file2
-c 按照标准个数输出
-I 忽略大小写
6. dircmp : dircmp options directory1 directory2
-s 不显示相同的文件
7. dirname : dirname pathname
8. du : du options directory
-a 显示每个文件的大小,不仅是整个目录所占用的空间
-s 只显示总计
9. file : file filename
10. fuser : fuser options file
-k 杀死所有访问该文件或文件系统的进程
-u 显示访问该文件或文件系统的进程
11. head : head -number files
12. logname : logname (显示当前使用的登陆用户名)
13. mkdir : mkdir options directory
-m 在创建目录时按照该选项的值设置访问权限
14. more : more options files
-c 不滚屏,而是通过覆盖来换页
-d 在分页处显示提示
-n 每屏显示n行
15. nl : nl options file
-I 行号每次增加n;缺省为1
-p 在新的一页不重新计数
16. printf : printf format arguments
17. pwd : pwd
18. rm : rm options files
-i 在删除文件之前给出提示(安全模式)
-r 删除目录
19. rmdir : rmdir options directory
-p 如果相应的目录为空目录,则删除该目录
20. script : script option file
-a 将输出附加在文件末尾
21. shutdown : shutdown now
22. sleep : sleep number(秒数)
23. strings : strings filename (查看二进制文件中的文本)
24. touch : touch options filename
-t MMDDhhmm 创建一个具有相应月,日,时分时间戳的文件
25. tty : tty 显示所连接的设备或终端
26. uname : uname options
-a 显示所有信息
-s 系统名
-v 只显示操作系统版本或其发布日期
27. uncompress : uncompress files
28. wait : wait processID
29. wc : wc options files
-c 显示字符数
-l 显示行数
-w 显示单词数
30. whereis : whereis command_name
31. who : who options
-a 显示所有的结果
-r 显示当前的运行级别
-s 列出用户名及时间域


AWK学习笔记:
==================================================
1、匹配第4列包含"Brown"的行
awk '{if($4~/Brown/) print $0}' grade.dat
2、匹配第1列包含 Brown 或 Yellow的 行
awk '{if($1 ~ /Brown/ || $1 ~ /Yellow/) print $0}' grade.dat
3、匹配第3列等于"48"的行
awk '$3!="48"{print $0}' grade.dat
4、内置变量的用法:
3.1、NR: 已读的记录数: awk '{print $0}END{print NR}' grade.dat
3.2、NF: 浏览记录的域个数: awk '{print NF"  "NR"  "$0}END{print FILENAME" has  counts: "NF}' grade.dat
NF还有一个强大的功能是将变量$pwd的值传入awk并显示其目录,如:echo "bossapp/lele/into" | awk -F/ '{print $0}'
5、awk操作符
设置域变量名: awk '{name=$1;belts=$4; if(belts ~ /Yellow/) print name " is belt "belts}' grade.dat
awk 'BEGIN{scolor="Yellow"}{name=$1;belts=$4; if(belts == scolor) print name " is belt "belts}' grade.dat
修改域的值:awk '{if($4 ~ /Brown/) {$4="new Brown";$6 -= 1};print $0}' grade.dat
创建新的域:awk 'BEGIN{newfield=0}{newfield=$6+$7; print $0 "\t" newfield; OFS="----"}' grade.dat
求某列值总和: awk '{total += $6;}END{print "Club student total points : "total}' grade.dat
打印某个目录下所有文件名及其大小:
ls -l | awk ' /^[^d]/ {print $8"\t"$5; total += $5} END{print "all files size is : " total}'
6、awk内置字符串函数
gsub(s,t): awk ' gsub(/48311/, a) {print $0}' grade.dat
index(s,t): awk '{print index($1,"M.")}' grade.dat
length(s): awk '{print length($3)}' grade.dat
match(str,reg): awk '{print match($1,/^J/)}' grade.dat
split(str,arr,fx): awk '{split("a/b/c/d", arr, "/"); print arr[1]}' grade.dat
sub(reg, str): awk '{str="poped popo kell"; sub(/op/, "OP", str); print str}' grade.dat
substr(str, i, len): awk 'BEGIN{str="poped popo kell"}END{print substr(str, 1, 5)}' grade.dat
$str = "poped popo kell"
echo $str | awk '{print substr($0,1,7)}'
7、awk的printf函数
echo "11" | awk '{printf "%x\n",$0}'
awk '{printf "%-15s %s\n",$1,$2}' grade.dat
awk '{AGE = 29; if($7 < AGE) print $0}' grade.dat
df | awk '{print $3}'
==================================================
sed学习笔记:
==================================================
1、匹配指定行
sed -n '2p' quote.dat
2、匹配指定范围的行
sed -n '1,3p' quote.dat
3、匹配包含某单词的行
sed -n '/honeysuckle/p' quote.dat
4、匹配以ing结尾的某单词的行
sed -n '/.*ing/p' quote.dat
sed -n '/.*ing/=' -e '/.*ing/p' quote.dat
5、替换文本
sed 's/night/NIGHT/' quote.dat        只替换第一次出现的night
sed 's/night/NIGHT/g' quote.dat        替换全局所有的night
sed 's/night/NIGHT/w sed.out' quote.dat  将修改结果输出到文件sed.out
6、插入
sed -n 's/night/light &/p' quote.dat        在night前插入light
sed 's/The/& addword/' quote.dat        在The后插入addword
7、将sed结果写入文件
sed '1,2 w sed.out' quote.dat            将quote.dat的第1、2行写入到sed.out文件中
8、在指定行的下一行,附加另外一个文件的内容
sed '/night/r sed.out' quote.dat
9、首次匹配到某单词后退出
sed '/music/q' quote.dat
sed 's/^M//q' quote.dat
9、例:去掉路径前的/ , 在最后加一个/
echo $PWD | sed 's/\///' | awk -F/ '{print $0"\/"}'
小结:sed 命令主要用于文本过滤及处理
==================================================
sort、uniq学习笔记
==================================================
sort:
1、按逆序排序
sort -r vid.dat
2、按指定域排序
sort -t: +1 vid.dat
3、对于数值列排序
sort -t: +2 vid.dat            先按第一个数字进行排列,再按第二个数字排列,依此类推。和字符排列一样
sort -t: +2n vid.dat        按数值大小排序
4、从某域的第n个字符开始排序
sort -t: +2.2n vid.dat
5、指定域从1开始计数
sort -t: -k1 vid.dat
6、删除重复的行
sort -u +5 vid.dat
uniq:
7、只显示不重复行
uniq -u a1.c
8、只显示重复的一行
uniq -d a1.c
9、显示复重的行数
uniq -c a1.c
10、只按某个域进行重复排序
uniq -f2 ab.c
join:
11、连接join
join ab.c abc.c
12、左连接
join -a1 ab.c abc.c
13、右连接
join -a2 ab.c abc.c
14、显示指定的域
join -o 1.1,1.2,2.1,2.2 ab.c abc.c
15、指定匹配域连接
join -j1 1 -j2 1 ab.c abc.c
cut:
16、以":"为分隔符,剪切域1
cut -d: -f1 vid.dat
17、以":"为分隔符,剪切域1、3
cut -d: -f1,3 vid.dat
18、以":"为分隔符,剪切域1至3
cut -d: -f1-3 vid.dat
19、以空格为分隔符,剪切域1
cut -d" " -f1 grade.dat
paste:
20、粘贴两个域,以@为分隔符
paste -d@ ab.c abc.c
21、把列变成行来粘贴
paste -s ab.c abc.c
22、管道输入,"-"接受变量输入
ls | paste a1.c -
split:
23、默认按1000行分割,保存为x[aa]--x[zz]
split grade.dat
24、指定行数进行分割
split -2 grade.dat
==================================================
tr学习笔记
==================================================
1、消除重复的字符串序列
tr -s "[a-z]" < oo.dat    : 消除重复的小写字母
tr -s "[0-9]" < oo.dat    : 消除重复的数字
2、删除空行
tr -s "[\n]" < oo.dat
3、从大字转换成小写
tr "[A-Z]" "[a-z]" < oo.dat
4、删除末行的控制字符 "^M"
tr -s "[\r]" "[\n]" < data.f | cat -v
小结:常用于删除空行,大小字替换,删除控制字符
==================================================Shell变量学习笔记
==================================================1、若变量定义,则使用默认值
echo ${variable-name:-defaultValue}
2、若变量定义,则输出错误信息
echo ${variable-name:?}    输出系统错误信息
echo ${variable-name:?"my error message"}    输出自定义错误信息
3、将变量设置成只读
readonly variable-name
4、查看所有系统变量
env
5、系统变量必须用export命令导出
6、设置传入变量
$0为脚本名
$1 为第1个参数
例如:
脚本myScript
find . -name $1 -print
调用:myScript myparam
其中myparam当作参数($1)传给脚本中的find命令
7、一些特定参数变量
$? : 显示最后一个命令退出状态,0为成功,其他值表明的错误
$# : 传递到脚本的参数的个数
$$ : 显示脚本运行的当前进程ID号
$* : 以一个字符串显示所有参数
$@ : 在引号中返回各个参数
==================================================条件测试 test 学习笔记
==================================================1、文件测试
有如下参数
-r : 可读
-w : 可写
-x :可执行
-d :目录
-f :正规文件
-u :文件有suid设置
例:
test -x wow
[ -x wow ]
可以将两个测试结果进行与或操作
-a : 与 [ -w wow -a -w wow ]
-o :或 [ -w wow -o -w wow ]
2、字符串测试
有五种格式
test "string"
test operator "string"
test "string" operator "string"
[ operator "string" ]
[ "string" operator "string" ]
其中,operator可以为:
= :两个字符串相等
!= :两个字符串不等
-z : 空串
-n : 非空串
3、数值测试
格式:
test "number1" operator "number2"
[ "number1" operator "number2" ]
其中,operator可以为:
-eq :两数相等
-ne :两数不相等
-gt :>
-lt :<
-ge :>=
-le :<=
4、expr的用法
4.1 expr用于数值计算
如:expr 1 + 2
expr 5 \* 3
expr 5 / 3 : 结果为1,不保留小数位
4.2 用例:用于循环计数
loop=0
loop=`expr $loop + 1`
4.3 expr用于字符串
expr "a" = "a" : 特别需要注意的是,如果成功返回1,返回其它值为错误
4.4 expr用于模式匹配
value="accounts.doc"
expr $value : ".*"     统计任意字符出现的次数,也就说统计单词的个数
expr $value : ".c"         统计c出现的
==================================================控制结构(while、for、until loop、if then else)
==================================================一、if then else 结构
格式: if 条件1; then
语句1;
elif 条件2; then
语句2;
fi
例1:名字为空,则输出信息
#!/bin/sh
echo -n "Please Enter your name:";
read NAME;
if [ "$NAME" = "" ]; then
echo "you havn't Enter your name!";
fi
例2、用户输入名字列表,脚本判断是否包含peter
#!/bin/sh
echo -n "Please Enter your name:";
read NAMELIST
if echo $NAMELIST | grep "peter" > inle/null 2>&1
then
echo "peter is here";
else
echo "peter is not here";
fi
例3、文件复制输出检查。自定义错误信息
#!/bin/sh
if cp wow wow_copy >>inle/null 2>&1
then
echo "复制成功!";
rm wow_copy;
else
echo "脚本`basename $0`发生错误,原因为: cp命令发生错误";
fi
例4、当前目录测试
#!/bin/sh
DIRNOW=`pwd`
if [ "$DIRNOW" != "/" ]
then
echo "your are not at the dir of / " >&2
exit 1
fi
例5、测试传递到脚本的参数
#!/bin/sh
if [ $# != 3 ]
then
echo "`basename $0`的参数个数不正确!应该为3个" >&2
exit 1
fi
echo "arg1: $1"
echo "arg2: $2"
echo "arg3: $3"
例6、登陆测试脚本,用户名和密码必须是peter/hellen--123
#!/bin/sh
#设置登陆标志
INVAIL_USER=yes
INVAIL_PWD=yes
#保存当前stty设置
SAVESTTY=`stty -g`
echo "welcome to XX System for unix, now you will login to the system"
echo "please Enter your username:"
read USERNAME
#设置输入密码时不可见
stty -echo
echo "please Enter your password:"
read USERPWD
#恢复之前stty设置
stty echo
if [ "$USERNAME" = "peter" -o "$USERNAME" = "hellen" ]
then
INVAIL_USER=no
fi
if [ "$USERPWD" = "123" ]
then
INVAIL_PWD=no
fi
if [ "$INVAIL_USER" = "no" -a "$INVAIL_PWD" = "no" ]
then
echo "now you have login into System"
else
echo "username or password is invaild, please check them and login next time"
exit 1
fi
二、case
例7、一个简单的case例子,其中配置部份可以用"|"来作为或命令
#!/bin/sh
echo "please Enter your choose:"
read ANS
case $ANS in
1) echo "you have selected 1"
;;
2) echo "you have selected 2"
;;
3) echo "you have selected 3"
;;
4) echo "you have selected 4"
;;
5) echo "you have selected 5"
;;
*) echo "`basename $0`发生错误: the choose is not between 1 and 5" >&2
esac
三、for
格式:
for 变量 in 列表
do
程序体
done
其中,列表可以是Shell命令
例8、一个最简单的for循环
#!/bin/sh
for loop in 1 2 3 4 5
do
echo $loop
done
例9、将ls的结果打印出来
#!/bin/sh
for loop in `ls`
do
echo $loop
done
例10、将参数打印出来
#!/bin/sh
for loop in $*
do
echo $loop
done
例11、在for程序体中使用find,实现多文件查找
for loop
do
find . -name $loop -print
done
例12、统计当前目录下的文件数目
#!/bin/sh
count=0
for loop in *
do
count=`expr $count + 1`
done
echo "there is $count files"
其实用ls | wc -l 也能统计出当前目录下文件的个数
四、until
例13、查看root用户是否登陆,登陆则给其发个邮件
#!/bin/sh
IS_ROOT=`who | grep root`
until [ "$IS_ROOT" ]
do
sleep 5
echo "no login"
done
五、while
例14、输出1-10
#!/bin/sh
i=0
while [ $i -lt 10 ]
do
echo $i
i=`expr $i + 1`
done
例15、从键盘读字符串,按ctrl+D结束读入
#!/bin/sh
echo -n "Enter: "
while read name
do
echo "output: $name"
done
例16、用while循环读取文件的每一行
#!/bin/sh
while read FLINE
do
echo $FLINE
done < data.f
例17、以:为分隔符,依次读取域信息
#!/bin/sh
SAVEIFS=$IFS
IFS=:
while read NAME DEPT
do
echo "$NAME\t $DEPT\t"
done < name.txt
IFS=$SAVEIFS
例18、默认以空格为域分隔符
#!/bin/sh
while read f1 f2
do
echo "$f1-----------$f2"
done < name.txt
说明下:无论是以什么作为分隔符,read后面的变量个数要与域的个数相同,这样就可以用变量一一对应域了
例19、每回读两行
#!/bin/sh
while read rline1
do
read rline2
echo $rline1
echo $rline2
echo "--------------------------"
done < name.txt
例20、while循环和文件描述符 做文件备份,按行读取,写到另一个文件
#!/bin/sh
FNAME=wow
FNAME_BAK=wow.bak
if [ -s $FNAME ]; then
#将wow描述为输入文件
exec 3<$FNAME
#将wow描述为输出文件
exec 4>$FNAME_BAK
while :
do
read LINE
if [ "$?" != "0" ]; then
#关闭输入和输出
exec 3<&-
exec 4<&-
exit 0
fi
echo $LINE >&4
done  <&3
else
echo "文件不存在!"
fi
六、break、continue
break 2 可以跳出两重循环
例21、用break(continue)跳出两重循环
#!/bin/sh
while :
do
echo "这是第一重循环"
while :
do
echo "这是第二重循环"
break 2
done
done
==================================================自定义函数
==================================================1、定位文件: . 文件名
这样就可以把文件中包含的函数当成系统函数了,直接调用即可,但只能在本终端运行,离开本终端就不行了
例22、自定义查找函数,可查找多个文件
#!/bin/sh
myfind() {
if [ $# -lt 1 ]; then
echo "至少有一个参数"
return 1
fi
for loop in "$@"
do
find . -name $loop -print
done
}
例23、检查名字是否全是英文
#!/bin/sh
#定义检查函数
check_name() {
_PARAM_NAME=$1
_PARAM_NAME=`echo $1 | awk '{if($0 ~ /^[a-zA-Z]+$/) print "1"}'`
if [ "$_PARAM_NAME" != "" ]; then
return 0
else
return 1
fi
}
#定义错误提示函数
name_error() {
echo "$@ 包含非法字符,请确保全部是英文字母"
}
#开始调用
while :
do
echo "请输入你的姓氏:"
read FIRST_NAME
if check_name $FIRST_NAME; then
break
else
name_error $FIRST_NAME
fi
done
while :
do
echo "请输入你的名字:"
read SEC_NAME
if check_name $SEC_NAME; then
break
else
name_error $SEC_NAME
fi
done
echo "你的名字为:$FIRST_NAME $SEC_NAME"

==================================================向脚本传递参数

==================================================一、shift的作用:指向参数的位置偏移一位,从1开始
例24、用shift实现参数位置偏移
#!/bin/sh
while [ $# -ne 0 ]
do
echo $1
shift
done

例25、自定义大小写转换命令
#!/bin/sh
#文件内容的大小写转换命令
FNAME=""
OPT="no"
CASEOPT=""
#自定义错误函数
error_msg() {
echo "`basename $0`: Error the conversion faild, please enter `basename $0` -help" &2
exit 1
}

#大小写转换
l_u_case() {
for LOOP in $FNAME
do
case $CASEOPT in
lower)cat $LOOP | tr "[a-z]" "[A-Z]" >>l_rslt.dat
;;
upper)cat $LOOP | tr "[a-z]" "[A-Z]" >>u_rslt.dat
;;
esac
done
}

#若不输入参数,则报错
if [ $# -eq 0 ]
then
error_msg
fi

#循环遍历参数,进行处理
while [ $# -gt 0 ]
do
case $1 in
-l)OPT="yes"
CASEOPT="lower"
shift
;;
-u)OPT="yes"
CASEOPT="upper"
shift
;;
-help)echo "this is help"
exit 0
;;
-*) error_msg
;;
*) FNAME=$1
OPT="no"
shift
;;
esac
done

#下面开始处理文件
if [ $OPT = "no" ]
then
if [ -f $FNAME ]
then
l_u_case
exit 0
else
echo "$FNAME is not a file ,please check it"
exit 1
fi
else
exit 0
fi

二、getopts: 获取用"-"开始的参数,如-fu, 其作用与-f -u 是一样的
例26、
#!/bin/sh
while getopts :afu: OPTS
do
case $OPTS in
a)echo "ALL"
;;
f)echo "FULL"
;;
u)echo "USER"
;;
\?)echo "error" >&2
exit 1
;;
esac
done

例27、-u选项必须带值,否则报错(若要屏蔽系统错误,在前面加:即可); 带入的值用变量OPTARG接收
#!/bin/sh
while getopts :afu: OPTS
do
case $OPTS in
a)echo "ALL"
;;
f)echo "FULL"
;;
u)echo "USER--$OPTARG"
;;
\?)echo "error"
exit 1
;;
esac
done

==================================================一些比较杂的东西
==================================================一、信号:系统向脚本发出的信息或命令,有如下含义:
信号            信  号  名                     含     义
1                     SIGHUP                             挂起或父进程被杀死
2                     SIGINT                              来自键盘的中断信号,通常是ctrl + c
3                     SIGQUIT                            从键盘退出
9                     SIGKILL                       无条件中止
11                   SIGSEGV                           段(内存冲突)
15                   SIGTERM                           软件中止,默认的

二、捕捉信号
trap
例28、当按下键盘中止后,用trap捕捉到信号,进行处理
#!/bin/sh
trap "tp_cmd" 2

tp_cmd() {
echo "hahahaha"
exit 1
}
loop=0
while :
do
loop=`expr $loop + 1`
echo $loop
sleep 1
done

例29、在某一段关键处理过程,可以屏蔽信号,从而保证完整性
#!/bin/sh
#设置屏蔽信号
trap "echo you can't interrupt me" 1 2 3 15

###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9  begin
loop=0
while :
do
loop=`expr $loop + 1`
echo $loop
if [ "$loop" -eq "6" ]
then
break
fi
sleep 1
done
###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9  end

#自定义退出函数
myexit() {
echo "hahahaha"
exit 1
}
##现在可以打断了,没关系
trap "myexit" 1 2 3 15
while :
do
loop=`expr $loop + 1`
echo $loop
sleep 1
done

三、eval
例30、自动生成变量
#!/bin/sh
loop=0
name="a"
while :
do
loop=`expr $loop + 1`
eval `echo "$name$loop=$loop"`
echo $name$loop=$loop
if [ "$loop" -eq "6" ]
then
exit 0
fi
done
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: