先写变量名,紧接着是“=”,最后是值,中见无空格。变量不区分变量类型,如需要指定变量类型可以使用declare显示定义变量类型。变量可分为环境变量和普通(局部)变量。shell的环境变量用来确定登陆的用户名、命令路径、终端类型、登录目录。永久保存环境变量,可以在用户家目录下的.bash_profile或.bashrc(非用户登录,如ssh)或/ect/profile中定义。
set、env、declare。set输出所有变量,env只显示全局变量,declare所有变量函数和已经导出的变量。set -o 显示bash shell的所有配置。
export a=value
a=value;export a
declare -x a=value
用户环境变量,/home/家目录/.bashrc(bash_profile);全局环境变量,/etc/profile(bashrc),/etc/profile.d/。
修改/etc/motd
在/etc/profile.d/下增加echo脚本
1.a=‘vaule’;2.a=value;3.a=“value”
a 表 示 输 出 变 量 , 也 可 以 用 {a} 表示输出变量,也可以用 a表示输出变量,也可以用a。
"双引号符号变量值连续输出字符,输出变量名的值;'单引号变量值原样输出。
[root@master ~]# a=12
[root@master ~]# echo '$a'
$a
[root@master ~]# echo "$a"
12
[root@master ~]# echo '${a}'
${a}
[root@master ~]# echo "${a}"
12
a=$(ls)等价于a=ls
[root@master ~]#cmd=`ls`;echo $cmd
[root@master ~]#cmd=$(ls);echo $cmd
[root@master ~]#cmd=$(data+%F);echo $cmd
[root@master ~]#echo $(data+%F).tar.gz
[root@master ~]#tar zcf etc_$(date+%F).tar.gz /etc/
.关于date和’’、""、’’
[root@master ~]#echo "today is date"
[root@master ~]#today is date
[root@master ~]# echo 'today is date'
[root@master ~]#today is date
[root@master ~]#echo "today is `date`"
[root@master ~]#today is Tue May 29 20:09:51 PDT 2018
[root@master ~]#OLDBAY=testchars
[root@master ~]#echo $OLDBOY
[root@master ~]#testchars
[root@master ~]#echo "$OLDBOY"
[root@master ~]#testchars
[root@master ~]#echo '$OLDBOY'
[root@master ~]#$OLDBOY
[root@master ~]#cat grep.log
testchars
oldboy
[root@master ~]#grep "$OLDBOY" grep.log
[root@master ~]#testchars
[root@master ~]#grep $OLDBOY grep.log
[root@master ~]#testchars
[root@master ~]#grep '$OLDBOY' grep.log
a=value或者a="value"或者a=‘value’**
grep
[root@master ~]a="value"
[root@master ~]#cat >> value<< EOF
[root@master ~]#> value
[root@master ~]#> EOF
[root@master ~]#grep $a log
[root@master ~]#value
[root@master ~]#grep '$a' log
[root@master ~]#grep "$a" log
[root@master ~]#value
[root@master ~]#grep $a log
[root@master ~]#value
[root@master ~]#grep `$a` log
[root@master ~]#syntax error
awk
[root@master ~]a="value"
[root@master ~]#awk 'BEGIN {printf "$a"}'
[root@master ~]#$a
[root@master ~]#awk 'BEGIN {printf '$a'}'
[root@master ~]#awk 'BEGIN {printf $a}'
[root@master ~]#awk 'BEGIN {printf `$a`}'
[root@master ~]#syntax error
[root@master ~]# a=`pwd`
[root@master ~]#awk 'BEGIN {printf "$a"}'
[root@master ~]#$a
[root@master ~]#awk 'BEGIN {printf '$a'}'
[root@master ~]#syntax error
[root@master ~]#awk 'BEGIN {printf $a}'
[root@master ~]#awk 'BEGIN {printf `$a`}'
[root@master ~]#syntax error
为了避免以上情况用echo给awk输出
[root@master ~]#a='value'
[root@master ~]#echo $a | awk '{printf $0}'
[root@master ~]#value
[root@master ~]#echo "$a" | awk '{printf $0}'
[root@master ~]#value
[root@master ~]#echo '$a' | awk '{printf $0}'
[root@master ~]#$a
[root@master ~]#a=`pwd`
[root@master ~]#echo $a | awk '{printf $0}'
[root@master ~]#/root
[root@master ~]#echo "$a" | awk '{printf $0}'
[root@master ~]#/root
[root@master ~]#echo '$a' | awk '{printf $0}'
[root@master ~]#$a
$0:脚本执行名称及路径
$n:参数值
$#:参数个数
$@、$*不加""获取传递的所有参数
$@加""获取所有参数视为不同的字符串,返回数组,$*加""获取所有参数视为一个字符串。
[root@master ~]# echo {1..12}
1 2 3 4 5 6 7 8 9 10 11 12
[root@master ~]# echo ${1..12}
-bash: ${1..12}: bad substitution
[root@master ~]# echo \${1..12}
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12
[root@master ~]# echo $11 $12 $13
1 2 3
查看当前系统语言环境:
[root@master ~]# echo $LANG
en_US.UTF-8
查看安了哪些中文语言包
[root@master ~]# locale -a |grep "zh_CN"
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
没有输出,说明没有安装,输入下面的命令安装
[root@master ~]# yum groupinstall "fonts" -y
[root@master ~]# locale -a |grep "zh_CN"
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
说明系统已安装中文语言包,无需再安装。重要提示,如果按照下面的步骤你的系统仍然无法使用中文,那么请一个一个尝试上面的编码方式。比如把LANG="zh_CN.GBK"修改为LANG=“zh_CN.UTF-8”。
设置中文,建议做备份,
[root@master ~]# vim /etc/locale.conf
LANG="en_US.UTF-8"
将下面的代码复制到配置/etc/locale.conf文件中
LANG=“zh_CN.GBK”
LANGUAGE=“zh_CN.GB18030:zh_CN.GB2312:zh_CN”
SUPPORTED=“zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en”
SYSFONT=“lat0-sun16”
使立即生效
[root@master ~]source /etc/locale.conf
打开环境变量配置文件
[root@master ~]vim /etc/profile
export LANG=zh_CN.GBK
使立即生效
[root@master ~]source /etc/profile
[root@master ~]# help read
read [-rs] [-a ARRAY] [-d delim] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [var_name1 var_name2 ...]
read命令用于从标准输入中读取输入单行,并将读取的单行根据IFS变量分裂成多个字段,并将分割后的字段分别赋值给指定的变量列表var_name。第一个字段分配给第一个变量var_name1,第二个字段分配给第二个变量var_name2,依次到结束。如果指定的变量名少于字段数量,则多出的字段数量也同样分配给最后一个var_name,如果指定的变量命令多于字段数量,则多出的变量赋值为空。
如果没有指定任何var_name,则分割后的所有字段都存储在特定变量REPLY中。
选项说明:
-a:将分裂后的字段依次存储到指定的数组中,存储的起始位置从数组的index=0开始。
-d:指定读取行的结束符号。默认结束符号为换行符。
-n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
-N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
-p:给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"
-r:禁止反斜线的转义功能。这意味着""会变成文本的一部分。
-s:静默模式。输入的内容不会回显在屏幕上。
-t:给出超时时间,在达到超时时间时,read退出并返回错误。也就是说不会读取任何内容,即使已经输入了一部分。
示例1
将读取的内容分配给数组变量,从索引号0开始分配。
[root@xuexi ~]# read -a array_test
what is you name?
[root@xuexi ~]# echo ${array_test[@]}
what is you name?
[root@xuexi ~]# echo ${array_test[0]}
what
示例2
指定读取行的结束符号,而不再使用换行符。
[root@xuexi ~]# read -d '/'
what is you name \// # 输入完尾部的"/",自动结束read
由于没有指定var_name,所以通过$REPLY变量查看read读取的行。
[root@xuexi ~]# echo $REPLY
what is you name /
示例3
限制输入字符。输入了5个字符后就结束。
[root@xuexi tmp]# read -n 5
12345
[root@xuexi tmp]# echo $REPLY # 输入12345共5个字符
12345
如果输入的字符数小于5,按下回车会立即结束读取。
[root@xuexi ~]# read -n 5
123
[root@xuexi ~]# echo $REPLY
123
如果使用的是"-N 5"而不是"-n 5",则严格限制读满5个字符才结束读取。
[root@xuexi ~]# read -N 5
123\n4
[root@xuexi ~]# read -N 5
123 # 3后的回车(换行)算是一个字符
4
示例4
使用-p选项给出输入提示。
[root@xuexi ~]# read -p "pls enter you name: "
pls enter you name: Junmajinlong
[root@xuexi ~]# echo $REPLY
Junmajinlong
“-p"选项默认不带换行功能,且也不支持”\n"换行。但通过$'string’的方式特殊处理,就可以实现换行的功能。
[root@node2 ~]# read -p $'Enter your name: \n'
Enter your name:
JunMaJinLong
示例5
禁止反斜线转义功能。
[root@xuexi ~]# read -r
what is you name \?
[root@xuexi ~]# echo $REPLY
what is you name \?
示例6
不回显输入的字符。比如输入密码的时候,不回显输入密码。
[root@xuexi ~]# read -s -p "please enter your password: "
please enter your password:
[root@xuexi ~]# echo $REPLY
123456
示例7
将读取的行分割后赋值给变量。
[root@xuexi ~]# read var1 var2 var3
abc def galsl djks
[root@xuexi ~]# echo $var1:::$var2:::$var3
abc:::def:::galsl djks
示例8
给出输入时间限制。没完成的输入将被丢弃,所以变量将赋值为空(如果在执行read前,变量已被赋值,则此变量在read超时后将被覆盖为空)。
[root@xuexi ~]# var=5
[root@xuexi ~]# read -t 3 var
1
[root@xuexi ~]# echo $var
参数
-n 不要在最后自动换行
-e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出。
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;
–help 显示帮助
–version 显示版本信息
[root@localhost test]# echo "Hello World"
Hello World
[root@localhost test]# echo Hello World
Hello World
[root@localhost test]# echo 'Hello World'
Hello World
上述三种方法看起来相似,但是各有一些特殊的用途和副作用。
[root@localhost test]# echo "Hello World!"
-bash: !": event not found
报错了,感叹号在双引号中竟然报错了,说明在双引号中不能使用叹号,只能在单引号或者不使用引号的情况下使用感叹号,如果需要在双引号中使用,则需要对感叹号转义。
[root@localhost test]# echo 'Hello World!'
Hello World!
[root@localhost test]# echo Hello World!
Hello World!
注意:Linux很多符号都是转义的,尽量不要使用双引号
打印彩色输出
示例1
[root@master ~]# echo -e "\033[30m 黑色字 \033[0m"
[root@master ~]# echo -e "\033[31m 红色字 \033[0m"
[root@master ~]# echo -e "\033[32m 绿色字 \033[0m"
[root@master ~]# echo -e "\033[33m 黄色字 \033[0m"
[root@master ~]# echo -e "\033[34m 蓝色字 \033[0m"
[root@master ~]# echo -e "\033[35m 紫色字 \033[0m"
[root@master ~]# echo -e "\033[36m 天蓝字 \033[0m"
[root@master ~]# echo -e "\033[37m 白色字 \033[0m"
[root@master ~]# echo -e "\033[40;37m 黑底白字 \033[0m"
[root@master ~]# echo -e "\033[41;37m 红底白字 \033[0m"
[root@master ~]# echo -e "\033[42;37m 绿底白字 \033[0m"
[root@master ~]# echo -e "\033[43;37m 黄底白字 \033[0m"
[root@master ~]# echo -e "\033[44;37m 蓝底白字 \033[0m"
[root@master ~]# echo -e "\033[45;37m 紫底白字 \033[0m"
[root@master ~]# echo -e "\033[46;37m 天蓝底白字 \033[0m"
[root@master ~]# echo -e "\033[47;30m 白底黑字 \033[0m"
控制选项说明 :
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m – \33[37m 设置前景色
\33[40m – \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标
背景颜色映射表
代码 | 颜色值 |
---|---|
0 | 重置 |
40 | 黑色 |
41 | 红色 |
42 | 绿色 |
43 | 黄色 |
44 | 蓝色 |
45 | 洋红 |
46 | 青色 |
47 | 白色 |
字体颜色映射表
代码 | 颜色值 |
---|---|
0 重置 | |
30 | 黑色 |
31 | 红色 |
32 | 绿色 |
33 | 黄色 |
34 | 蓝色 |
35 | 洋红 |
36 | 青色 |
37 | 白色 |
取得的值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
#!/bin/bash
echo 'Input a number:'
read Num
case $Num in
1) echo 'You select 1'
;;
2) echo 'You select 2'
;;
3) echo 'You select 3'
;;
4|5) echo 'You select 4 or 5'
;;
*) echo 'default'
;;
esac
#!/bin/bash
option=$1
case ${option} in
-f) echo "param is -f"
;;
-d) echo "param is -d"
;;
*)
echo "$0:usage: [-f ] | [ -d ]"
exit 1 #退出码
;;
esac
一般格式
for 变量 in 列表
do
command1
command2
...
commandN
done
列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。 in 列表是可选的,如果不用它,for 循环使用命令行的位置参数。
[root@master ~]# vim test.sh
#!/bin/bash
for var in 1 2 3 4 5
do
echo "The value is: $var"
done
[root@master ~]# bash test.sh
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
[root@master ~]# vim test.sh
#!/bin/bash
for str in 'This is a string'
do
echo $str
done
[root@master ~]# bash test.sh
This is a string
显示主目录下以 .bash 开头的文件
[root@master ~]# vim test.sh
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
[root@master ~]# bash test.sh
/home/where/.bash_history
/home/where/.bash_logout
/home/where/.bashrc
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while expression
do
...
done
[root@master ~]# vim test.sh
#!/bin/bash
COUNT=0
while [ $COUNT -lt 5 ]
do
COUNT=$(($COUNT + 1))
echo $COUNT
done
[root@master ~]# bash test.sh
1
2
3
4
5
while循环可用于读取键盘信息,输入信息被设置为变量FILM,按结束循环。
[root@master ~]# vim test.sh
#!/bin/bash
echo -n 'input film: '
while read FILM
do
echo "great film the $FILM"
done
[root@master ~]# bash test.sh
input film:gongfu
great film gongfu
函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,Shell 也支持函数。Shell 函数必须先定义后使用。
[root@master ~]# help function
function: function name { COMMANDS ; } or name () { COMMANDS ; }
Define shell function.
Create a shell function named NAME. When invoked as a simple command,
NAME runs COMMANDs in the calling shell's context. When NAME is invoked,
the arguments are passed to the function as $1...$n, and the function's
name is in $FUNCNAME.
Exit Status:
Returns success unless NAME is readonly.
function_name () {
[commands]
...
[ return value ]
}
可以在函数名前加上关键字 function:
function function_name () {
[commands]
...
[ return value ]
}
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。
如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
[root@master ~]# vim test.sh
#!/bin/bash
myfunc () {
echo "hello world"
}
myfunc
[root@master ~]# bash test.sh
hello world
调用函数只需要给出函数名,不需要加括号。
函数返回值
[root@master ~]# vim test.sh
#!/bin/bash
myfunc(){
echo "hello world"
return 5
}
myfunc
echo "myfunc return $?"
[root@master ~]# bash test.sh
hello world
myfunc return 5
函数返回值在调用该函数后通过 $? 来获得。
函数嵌套调用
[root@master ~]# ./test.sh
myfunc1
myfunc2
函数参数传递
[root@master ~]# vim test.sh
#!/bin/bash
myfunc () {
echo "myfunc $1 $2 $@"
}
myfunc
[root@master ~]# ./test.sh
myfunc 1 2 1 2 3
函数取消
像删除变量一样,删除函数也可以使用 unset 命令。
unset function_name
函数中定义变量
在函数中定义的变量在整个shell脚本中都能使用。
[root@master ~]# vim test.sh
#!/bin/bash
myfunc () {
echo "myfunc"
var=888
}
myfunc
echo $var
[root@master ~]# ./test.sh
where@ubuntu:~$ ./test.sh
myfunc
888
[root@master ~]# dir /server/sh.sh
[root@master ~]# /server
[root@master ~]# basename /server/sh.sh
[root@master ~]# sh.sh
[root@master ~]# cat n.sh
dirname $0
basename $0
[ $# -ne 2 ] && { echo ""; exit 1; }
if [ $# -ne 2]
then
echo;
exit 1;
fi
[root@resource yum]# if [ $# -ne 2 ];then echo "s"; fi;
s
生成脚本
[root@master ~]# echo ${1…12} >> a.sh
[root@master ~]# vim a.sh
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12
[root@master ~]# set -- "I am" handsome boy
[root@master ~]# echo $# $1 $2 $3
3 I am handsome boy
[root@master ~]# echo $*
I am handsome boy
[root@master ~]# echo $@
I am handsome boy
[root@master ~]# for i in $*;do echo $i;done;
I
am
handsome
boy
[root@master ~]# for i in $@;do echo $i;done;
I
am
handsome
boy
[root@master ~]# echo "$*"
I am handsome boy
[root@master ~]# echo "$@"
I am handsome boy
[root@master ~]# for i in "$*";do echo $i;done;
I am handsome boy
[root@master ~]# for i in "$@";do echo $i;done;
I am
handsome
boy
[root@master ~]# set -- "i am" handsome boy
[root@master ~]# shift
[root@master ~]# echo $1
handsome
[root@master ~]# echo $#
2
echo $1 $2
if [ $# -eq 2 ]; then
shift;
echo $1
fi
当shell执行到eval时,会将eval后的参数组合成一个新的命令执行。
[root@master ~]# set 11 22 33 44
#输出最后一个参数值
#得到结果为44
[root@master ~]# eval echo "\$$#"
#判断语句
[root@master ~]# cat a.sh
[ $# -ne 2 ] &&
{
echo "must have two args"
exit 119
}
#输出不换行
[root@master ~]#echo -n oldboy;echo oldboy;
oldboyoldboy
#行输入
while read line
do
echo $line;
done;
在不创建新子进程的情况下执行后面的语句,执行完毕后,进程退出,包括在终端下,执行完毕,终端退出登录。
[root@master temp]# vim a.sh
exec date
while read line
do
echo $line;
done;
$$获取当前执行的进程号; $! 获取上一次执行的进程号 ;
$_获取上一次执行的最后一个参数 ;
$? 获取返回值0 1 。
a = {a}= a=a
${#a}:获取a的长度
${a:offset}:获取offset后的子串
${a:offset:length}:获取offset后length的子串
${a:#subword}:从开头删除subword最短匹配子串
${a:##subword}:从开头删除subword最长匹配子串
${a:%subword}:从结尾删除subword最短匹配子串
${a:%%subword}:从结尾删除subword最长匹配子串
${a:/pattern/string}:用string替换第一个pattern匹配的字串
${a://pattern/string}:用string替换所有pattern匹配的字串
[root@master ~]# expr length $a
[root@master ~]# echo $a | wc -L
[root@master ~]# echo $a | awk '{printf length($0)}'
[root@master ~]# echo ${#a}
[root@master ~]# echo ${a#} //输出a的值,#忽略
[root@master ~]# a='abc$$$$$abc'
#abc不加''
[root@master ~]# echo ${a##abc}
#abc不加''
[root@master ~]# $$$$$abc
#全部删除
[root@master ~]# echo ${a##a*c} //abc不加''
[root@master ~]# f=str_finish.jpg
[root@master ~]# echo ${f//_finish/}
[root@master ~]# str.jpg
计算程序执行时间
[root@master ~]# time for i in seq 12 ;do sleep 1 ; done;
real 0m2.008s
user 0m0.005s
sys 0m0.000s
[root@master ~]# time for n in {1...1000}; do char=`seq -s "oldboy" 100`; echo ${char}/expr length $char/${char}|wc -L|awk '{print length($0)}';done
[root@master ~]# for f in `ls *fin*.jpg`;do mv $f `echo ${f//_finshd}`
${a:-word}:若a未赋值或为空,则用word替换a输出
${a:=word}:若a未赋值或为空,则用word赋值a输出a
${a:?word}:若a未赋值或为空,则用word作为报错信息输出
${a:+word}:若a未赋值或为空,什么都不做,若a赋值,用word代替a的值
[root@master ~]# find ${path:-/tmp} -name "*.tar.gz" -type f -mtime +9|xargs rm -f
$((a+b)) == $[a+b] 数字运算符
[root@master ~]# a=1
[root@master ~]# b=2
[root@master ~]# echo ((a+b))
-bash: syntax error near unexpected token `('
[root@master ~]# echo $((a+b))
3
[root@master ~]# echo $[a+b]
3
[root@master ~]# a=12;b=13
[root@master ~]# i=a+b
[root@master ~]# echo $i
a+b
[root@master ~]# a+b
-bash: a+b: command not found
[root@master ~]# ((i=a+b))
[root@master ~]# echo $i
25
#以上不能是浮点数,只能是整数
#在((和[内的变量可以去掉$
[root@master ~]# ((a=12*44)
> ^C
[root@master ~]# echo $((a=12*44))
528
[root@master ~]# ((i=12))
[root@master ~]# ((i=i*4))
[root@master ~]# echo $i
48
[root@master ~]# echo $((12<11))
0
[root@master ~]# a=1
[root@master ~]# echo $((a++))
1
[root@master ~]# echo $(($a++))
-bash: 2++: syntax error: operand expected (error token is "+")
[root@master ~]# vim caculate.sh
#!/bin/bash
a=$1;
b=$2;
echo "a+b=$((a+b))"
[root@master ~]# bash caculate.sh 11 22
a+b=33
[ -n “echo $num | sed 's/[0-9]//g'
”]
[ $? -eq 0 ] && echo int || echo chars
if […] && [ ]…
[ $? -eq 0 ] && echo int || echo chars
[root@master ~]# vim a.sh
echo $(($1))
[root@master ~]# ./a.sh 12+1
[root@master ~]# let a="+"
-bash: let: a=+: syntax error: operand expected (error token is "+")
函数调用不得加()
#!/bin/bash
num1=0
num2=0
let operator=1
function print_usage()
{
printf "please input an integer!"
exit 1
}
function unempty()
{
if [ -n "`echo ${num1} | sed 's/[0-9]//g'`"] && [ -n "`echo ${num2} |sed 's/[0-9]//g'`"]
then
print_usage;
fi
exit 0
}
function input1()
{
read -p "please input first number(input q quit):" num1
}
function input2()
{
read -p "please input second number(input q quit):" num2
}
function inputoperator()
{
read -p "please input operator(+-*/)" operator
while true
do
if [ "${operator}" = "+" ] || [ "${operator}" = "-" ] || [ "${operator}" = "*" ] || [ "${operator}" = "/" ]
then
break
fi
done
}
while true
do
input1
if [ "${num1}" = "q" ] || [ "${num2}" = "q" ];then
break
fi
input2
if [ "${num1}" = "q" ] || [ "${num2}" = "q" ];then
echo $num1
break
fi
inputoperator
echo $(($num1$operator$num2))
done
[root@master ~]# let a=a++
[root@master ~]# c=$((a+b))
[root@master ~]# c=$[a+b]
[root@master ~]# let c=a+b
[root@master ~]# expr 2 + 2
[root@master ~]# expr 2 /* 2
[root@master ~]# unset i
[root@master ~]# i=expr 2 * 2
[root@master ~]# echo i 1. 可 以 计 算 整 数 也 可 以 计 算 浮 点 数 2. 数 字 和 运 算 符 之 间 必 须 有 空 格 , 否 则 原 样 输 出 3. 参 加 运 算 的 字 符 串 必 须 是 整 数 , 如 果 不 是 i 1.可以计算整数也可以计算浮点数 2.数字和运算符之间必须有空格,否则原样输出 3.参加运算的字符串必须是整数,如果不是 i1.可以计算整数也可以计算浮点数2.数字和运算符之间必须有空格,否则原样输出3.参加运算的字符串必须是整数,如果不是?为0
[root@master ~]# i=5
[root@master ~]# expr $i+6 &>/dev/null
[root@master ~]# echo $?
[root@master ~]# 0
STRING : REGEXP
anchored pattern match of REGEXP in STRING
match STRING REGEXP
same as STRING : REGEXP
substr STRING POS LENGTH
substring of STRING, POS counted from 1
index STRING CHARS
index in STRING where any CHARS is found, or 0
length STRING
length of STRING
if expr “$1” : “.*.pub” & >/dev/null then … //判断扩展名
for i in i am boy ; do [ expr length $i
-le 2 ] && echo … || echo … ;done;
输入的参数和默认的参数要通过一个变量赋值,否则就容易出现条件判断错误。
#!/bin/bash
argnum=$#
arg1=$1
function checkInteger(){
#[ "$#" -eq "0" ] && echo "please input interger"
#[ $# -eq 1 ] && echo "please input interger"
if [[ $argnum == 0 ]] then
echo "please input args"
fi
}
function main()
{
checkInteger
}
main
[root@master ~]# echo 'scale=3;4+12' | bc
[root@master ~]# seq -s "+" 1 12
1+2+3+4+5+6+7+8+9+10+11+12
[root@master ~]# echo {1..12} | tr ' ' '+'
1+2+3+4+5+6+7+8+9+10+11+12
[root@master ~]# echo `seq -s '+' 10` = `seq -s "+" 10 | bc`
1+2+3+4+5+6+7+8+9+10 = 55
[root@master ~]# echo `seq -s "+" 10` = `seq -s " + " 10 | xargs expr`
1+2+3+4+5+6+7+8+9+10 = 55
[root@master ~]# echo `seq -s "+" 10` = $((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10 = 55
[root@master ~]# echo `seq -s "+" 10` = $[ `seq -s '+' 10`]
1+2+3+4+5+6+7+8+9+10 = 55
[root@master ~]# echo "44 33" | awk '{ printf $1-$2}'
11
[root@master ~]# declare -i a=12 b=13
[root@master ~]# c=a+b
[root@master ~]# echo $c
a+b
[root@master ~]# read -p 'please input numer' -t 5 a b //a b不带$
please input numer-bash: read: `//a': not a valid identifier
test express
[ express ] express 两边有空格,不能用&& == >,只能用-a -o -gt -lt -eq
[[ express ]] express 两边有空格,是对[]的扩展,可以用 && == >
((express)) express 两边无空格
( EXPRESSION )
EXPRESSION is true
! EXPRESSION
EXPRESSION is false
EXPRESSION1 -a EXPRESSION2
both EXPRESSION1 and EXPRESSION2 are true
EXPRESSION1 -o EXPRESSION2
-n STRING
the length of STRING is nonzero
STRING equivalent to -n STRING
-z STRING
the length of STRING is zero
STRING1 = STRING2
the strings are equal
STRING1 != STRING2
the strings are not equal
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
FILE1 -ef FILE2
FILE1 and FILE2 have the same device and inode numbers
FILE1 -nt FILE2
FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2
FILE1 is older than FILE2
-b FILE
FILE exists and is block special
-c FILE
FILE exists and is character special
-d FILE
FILE exists and is a directory
-e FILE
FILE exists
-f FILE
FILE exists and is a regular file
-g FILE
FILE exists and is set-group-ID
-G FILE
FILE exists and is owned by the effective group ID
-h FILE
FILE exists and is a symbolic link (same as -L)
-k FILE
FILE exists and has its sticky bit set
-L FILE
FILE exists and is a symbolic link (same as -h)
-O FILE
FILE exists and is owned by the effective user ID
-p FILE
FILE exists and is a named pipe
-r FILE
FILE exists and read permission is granted
-s FILE
FILE exists and has a size greater than zero
-S FILE
FILE exists and is a socket
-t FD file descriptor FD is opened on a terminal
-u FILE
FILE exists and its set-user-ID bit is set
-w FILE
FILE exists and write permission is granted
-x FILE
FILE exists and execute (or search) permission is granted
file1=/etc/services;file2=/set/rc.local
[ -f "$file1" ] && echo 1 || echo 0
[ -e /etc ] && echo 1
[ "${NETWORKING}" == "no" ] && exit 6;
二者都一样
[ -f "/etc/services" ] && echo 1 || echo 0
[ -f /etc/services ] && echo 1 || echo 0
在[]使用-eq -ne -gt -ge -lt -le 来比较数字大小,在[[]]和(())中使用== = >= >等和-eq -ne -gt -ge -lt -le来比较。
[ contion ] && { .... }
[[ contion ]] && { .... }
test contion && { .... }
if [ contion ] ; then .... fi
[ "abc" == "abc"]
过滤出含有-eq的行
grep -w "\-eq" /etc/init.d/fns
[ 2 \<1 ] && echo 1
[[ 5< 6 ]] && echo 1
[[ 5 -gt 6 ]] && echo 1
((3<2)) && echo 1
(())不能使用-eq等写法,[[]]既可以使用-eq等写法,也可以使用<等写法,[]也可以使用<等写法,推荐使用-eq。
变量算术比较不用使用"":
[ $a > $b ] && echo 1
[[ $a > $b ]] && echo 1
(($a > $b]))&& echo 1
在[]和test中使用-a -o !
在[[]]和(())中使用&& !||
[ 5 -eq 6 -o 5 -gt 3 ] && echo 1
((5==6 || 5>3)) && echo 1
[ -z "$a" -o "$a" != "$b" ] && echo 1
通配符只适用于[[]]
if [[ "$source"=*" via "* ]]; then... fi
if [[ $sports" =~_r?ntedev ]]; then... fi
#!/bin/bash
var = $1
[ "$var" == "1" ] && {
echo 1
exit 0
}
[ "$var" == "2" ] && {
echo 2
exit 0
}
[ "$var" != "2" -a "$var" != "1" ] &&
echo error
exit 0
}
if [ "$var != "2" -a "$var" != "1"]
then
{
echo error
exit 0
}
fi
#!/bin/bash
echo -n "please input char" //-n不换行
read var
var = $1
[ "$var" == "1" ] && {
echo 1
exit 0
}
[ "$var" == "2" ] && {
echo 2
exit 0
}
[ "$var" != "2" -a "$var" != "1" ] &&
echo error
exit 0
}
(1)read -t 5 -p “please input two number:” a1 a2
(2)[[]]可以带模式匹配
(3)&&||两端可以有空格也可以没有空格
(4)test -z filename && echo true || echo false 判断文件是否为空
[ -f filename ] && echo exist || echo not exist判断文件是否存在
(5)f1 -ot f2 f1 older f2
f1 -nt f2 f1 newer f2
cat <<END
1.......
2.........
3.........
END
read -p "which do you like?" a
[ "$a" == "1" ] && { echo ... ; exit 0 ;}
[ "$a" == "2" ] && { ..... }
[ "$a" == "3" ] && { ..... }
[[ "$a" =~ [ 1-4 ] ]] && { ..... } 不等于1-4
path=/server/script
[ ! -d "$path" ] && mkdir &path -p
#menu
cat <<END
1.install lamp
2.install lnmp
3.exit
END
read num
expr &num+1 &>/dev/null
[ $? -ne 0 ] && {
echo "the num you input must be{1|2|3}"
exit 1
}
[ $num -eq 1] && {
echo "start installing lamp"
sleep 2;
[ -x "$paht/lamp.sh" ] || {
echo "$path/llamp.sh not exist or can not exec."
exit 1;
}
$path/lamp.sh
exit $?
}
[ $num -eq 2] && {
echo "start installing lnmp"
sleep 2;
[ -x "$paht/lnmp.sh" ] || {
echo "$path/llnmp.sh not exist or can not exec."
exit 1;
}
$path/lnmp.sh
exit $?
}
[ $num -eq 3] && {
echo "bye"
exit 3
}
[[ $num = ~[1-3] ]] && {
echo "input eror"
exit 4
}
if conition
then
…
elif conition
then
…
else
fi
if test 表达式
then
....
fi
if [ 字符串和算术表达式 ]
then
....
fi
if [[ 字符串表达式 ]]
then
....
fi
if ((算术表达式))
then
....
fi
if 命令
then
....
fi
#!/bin/bash
if `ls`
then
echo "fail"
fi
command not found
echo -e " set from [email protected] smtp=smtp.163.com set smtp-auth-user=oldboy smtp-auth-psassword=… smtp-auth=login >> /etc/mail.rc
echo “oldboy” | mail -s “title” [email protected]
mail -s “title” [email protected] < /tmp/test.txt
FreeMem=free -m | awk 'NR==3 {print $NF}'
Chars=“current memory is $FreeMem”
if [ $FreeMe -lt 100 ] then
echo $Chars | tee /temp/message.txt
mail -s "date +F -%T
$Chars" [email protected] < /temp/message.txt
fi
1.采用监控端口的方式,监控本地服务运行状态
# netstat -nlt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp6 0 0 :::111 :::* LISTEN
# netstat -nlt | grep 3306 | awk -F "[ : ]+" '{print $5}'
Address
111
80
22
3306
*
# netstat -lnutp | grep 3306 | wc -l
1
# netstat -lnutp | grep mysql| wc -l
1
# ss -lnutp | grep 3306 | wc -l
1
# ss -lnutp | grep mysql| wc -l
1
# lsof -i tcp:3306 | wc -l
# lsof -i:3306 | wc -l
2.采用远端监控服务器端口的方式,监控本地服务运行状态
# nmap 211.159.169.159 3306 | grep mysql | wc -l
1
# echo -e "\n" | telnet 211.159.169.159 3306 2>/dev/null | grep Connected | wc -l
1
# nc -w 2 211.159.169.159 3306 &>/dev/null
# echo $?
0
# ps -ef | grep mysql |grep -v grep | wc -l //服务器运行
3
# curl -s -o /dev/null 211.159.169.159 &>/dev/null
# echo $?
0
wget -T 10 -q --spider 211.159.169.159/index.html &>/dev/null
# echo $?
0
wget --timeout 10 --tries=2 --spider 211.159.169.159/index.html &>/dev/null
# echo $?
0
if [ `netstat -tnlp |grep 3306 | awk -F:[ : ] '{print $5}'` -eq 3306 ];
if [ "`netstat -tnlp |grep 3306 | awk -F:[ : ] '{print $5}'`" == "3306" ];
if [ `netstat -ltunlp | grep mysql | wc -l ` -gt 0 ];
if [ `lsof -i tcp:3306 | wc -l ` -gt 0 ];
then
echo "Mysqld is runing"
else
echo "Mysqld is stoped"
fi
if [ `rpm -qa nmap | wc -l` -lt 1 ] && yum install nmap -y &>/dev/null
if[ `nmap 211.159.169.159 -p 3306 2>/dev/null | grep open | wc -l ` -gt 0 ]
then
echo "Mysqld is runing"
else
echo "Mysqld is stoped"
fi
if [ `rpm -qa nmap | wc -l` -lt 1 ] && yum install nmap -y &>/dev/null
if[ `nc -w 2 211.159.169.159 3306 &>/dev/null && echo ok | grep ok | wc -l ` -gt 0 ]
then
echo "Mysqld is runing"
else
echo "Mysqld is stoped"
fi
if[ `ps -ef | grep -v grep | grep mysql | wc -l ` -gt 0 ]
then
echo "Mysqld is runing"
else
echo "Mysqld is stoped"
fi
# curl -I -s -w "%{http_code}\n" -o /dev/null 211.159.169.159
# `curl -I -s -w "%{http_code}\n" -o /dev/null 211.159.169.159 ` =~ [23[0[012]
if [ `curl -I 211.159.169.159 2>/dev/null | head -1 | egrep "200|302|301" | wc -l` -eq 1]
then echo "Nginx is running"
else echo "Nginx stoped"
fi
content_type The Content-Type of the requested document, if there was any.
filename_effective The ultimate filename that curl writes out to. This is only meaningful if curl is told to write to a file with the --remote-name or --output option. It's most useful in ombination with the --remote-header-name option. (Added in 7.25.1)
ftp_entry_path The initial path curl ended up in when logging on to the remote FTP server. (Added in 7.15.4)
time_namelookup
http_code The numerical response code that was found in the last retrieved HTTP(S) or FTP(s) transfer. In 7.18.2 the alias response_code was added to show the same info.
http_connect The numerical code that was found in the last response (from a proxy) to a curl CONNECT request. (Added in 7.12.4)
local_ip The IP address of the local end of the most recently done connection - can be either IPv4 or IPv6 (Added in 7.29.0)
local_port The local port number of the most recently done connection (Added in 7.29.0)
num_connects Number of new connects made in the recent transfer. (Added in 7.12.3)
num_redirects Number of redirects that were followed in the request. (Added in 7.12.3)
redirect_url When an HTTP request was made without -L to follow redirects, this variable will show the actual URL a redirect would take you to. (Added in 7.18.2)
remote_ip The remote IP address of the most recently done connection - can be either IPv4 or IPv6 (Added in 7.29.0)
remote_port The remote port number of the most recently done connection (Added in 7.29.0)
size_download The total amount of bytes that were downloaded.
size_header The total amount of bytes of the downloaded headers.
size_request The total amount of bytes that were sent in the HTTP request.
size_upload The total amount of bytes that were uploaded.
speed_download The average download speed that curl measured for the complete download. Bytes per second.
speed_upload The average upload speed that curl measured for the complete upload. Bytes per second.
ssl_verify_result The result of the SSL peer certificate verification that was requested. 0 means the verification was successful. (Added in 7.19.0)
time_appconnect The time, in seconds, it took from the start until the SSL/SSH/etc connect/handshake to the remote host was completed. (Added in 7.19.0)
time_connect The time, in seconds, it took from the start until the TCP connect to the remote host (or proxy) was completed. The time, in seconds, it took from the start until the name resolving was completed.
time_pretransfer The time, in seconds, it took from the start until the file transfer was just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.
time_redirect The time, in seconds, it took for all redirection steps include name lookup, connect, pretransfer and transfer before the final transaction was started. time_redirect shows the complete execution time for multiple redirections. (Added in 7.12.3)
time_starttransfer The time, in seconds, it took from the start until the first byte was just about to be transferred. This includes time_pretransfer and also the time the server needed to calculate the result.
time_total The total time, in seconds, that the full operation lasted. The time will be displayed with millisecond resolution.
url_effective The URL that was fetched last. This is most meaningful if you've told curl to follow location: headers.
wget -O /etc/yum.repos.,d/epel.repo http://mirrors.aliyun.com/repo/epel1-6.repo
yum install nginx -y
/etc/init.d/nginx start
curl http://127.0.0.1
通过命令检测nginx服务是否运行正常
netstat -lnt|grep -w 80 | awk -F "[ :]"+" '{print $5}'
netstat -lntip | grep -w 80 | wc -l
netstat -lntup | grep mysql | wc -l
ss -lntup | grep -w 80 | wc -l
ss -lntup | grep -w 80 | wc -l
lsof -i tcp:80 | wc -l
在远端监控服务器本地端口
namp 127.0.0.1 -p 80 | grep open | wc -l
echo -e "\n"|telnet 127.0.0.1 80 2>/dev/null |grep Connected | wc -l
nc-w 2 127.0.0.1 80 &>/dev/null && echo $?
对服务进程监控
ps -ef | grep nginx | grep -v | wc -l
ps -C nginx --no-header | wc -l
测试网站
wget --spider --timeour=10 --tries-2 http://127.0.0.1 &>/dev/null
echo &?
wget -T 10 -q --spider http://127.0.0.1 &>/dev/null
echo &?
curl -s -o /dev/null http://127.0.0.1
echo &?
curl -I -s -w "%{http_code}\n" -o /dev/null http://127.0.0.1
if [ `netstat -lnt | grep 80 |awk -F "[ :]+" '{print $5}'` -eq 80]
if [ "`netstat -lnt | grep 80 |awk -F "[ :]+" '{print $5}'`" ="80" ]
if [ `netstat -lntup | grep ngonx | wc -l` -gt 0]
if [ `lsof -i tcp:80 | wc -l ` -gt 0 ]
[ rpm -qa nmap | wc -l -lt 1 ] && yum install nmap -y &>/dev/null
if [ `nmap 127.0.0.1 -p 80 2 >/dev/null | grep open | wc -l ` -gt 0 ]
...................p141
[ `rpm -qa nc |wc -l` -lt 1 ] yum install nc -y &> /dev/null
if [ `nc -w 2 127.0.0.1 80 &>/dev/null && echo ok | grep ok | wc -l ` -gt 0 ]
if [ `ps -ef | grep -v grep | grep nginx | wc -l` -ge 1 ]
if [[ `curl -I -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1` =~[23]0[012] ]]
if [ `curl -I http://127.0.0.1 2 >/dev/null/head -1 | egrep "200|302|301" | wc -l ` -eq 1 ]
if [ "`curl -s http://127.0.0.1` " = "oo" ]
exper $a+1 $>/dev/null
RETVAL=$?
if [[ $RETVAL = 0 ]]
判断数字是否为空
if [ -z $a ]
-n 判断变量长度不为0
-z 判断变量长度为0
[ -n "`echo 123 | sed 's/[0-9]//g'`" ] && echo char || echo int ]
[ -z "`echo 123 | sed 's/[0-9]//g'`" ] && echo int || echo char ]
[ -z "`echo "${num//[0-9]/}"`" ] && echo int || echo char
[[ -n $num && "$num“ = "${num//[^0-9]/}" ] && echo "it is num"
[[ $num =~ ^[0-9]+$ ]] && echo int || echo char
[ -z "dddd" ] && echo 1 || echo 0
[ -n "dddd" ] && echo 1 || echo 0
[ ${#num} != 0] && echo 1 || echo 0
[ `expr length $num ` -eq 0 ] && echo 1 || echo 0
[ `echo $num | wc -L ` -eq 0] && echo 1 || echo 0
[ 'echo $num | awk '{print lenght}' ` -eq 0 ] && echo 1 || echo 0
vim test.php
<?php
$link_id = mysql_connect("hostname","user","password");
if($link_id)
{
echo "mysql successful"
}
else
{
echo mysql_error();
}
?>
#!/bin/bash
a=$1
b=$2
if [ $# -eq 2 ]
echo "$0 arg1 arg2"
exit 2
fi
expr $a+1 &>/dev/null
RETVAL1=$?
expr $b+1 &>/dev/null
RETVAL2=$?
if [ RETVAL1 -ne 0 -a RETVAL2 -ne 0 ]; then
echo "please input two int number"
exit 3
fi
if [ $a -lt $b ] ; then
echo "$a<$b"
elif [ $a -eq $b ] ; then
echo "$a=$b"
else
echo "$a>$b"
fi
#!/bin/bash
read -p "pls input two number" a b
expr $a+1 &>/dev/null
RETVAL1=$?
expr $b+1 &>/dev/null
RETVAL2=$?
if [ -z $a ] || [ -z $b ]
then
echo "please input two number again"
exit 1
fi
if [ RETVAL1 -ne 0 -a RETVAL2 -ne 0 ]; then
echo "please input two int number"
exit 3
fi
if [ $a -lt $b ] ; then
echo "$a<$b"
elif [ $a -eq $b ] ; then
echo "$a=$b"
else
echo "$a>$b"
fi
[ -n "`echo variable | sed 's/[0-9]//g`" ] && echo char || echo int
[ -z "`echo variable | sed 's/[0-9]//g`" ] && echo int || echo char
[ -n "`echo 123 | sed 's/[0-9]//g`" ] && echo char || echo int
[ -z "`echo 123 | sed 's/[0-9]//g`" ] && echo int || echo char
num=oldboy123
[ -z "`echo "${num//[0-9]/}"`" ] && echo int || echo char //不完善,如果num未定义
[ -n $num -a -z "`echo "${num//[0-9]/}"`" ] && echo int || echo char
expr $num+1 &/dev/num
echo $?
[[ 123=~^[0-9]+$ ]] echo int || echo char
# echo oldboy | bc
0
# echo 23 | bc
23
# [ -z "old" ] && echo 1 || echo 0
# [ -n "old" } && echo 1 || echo 0
# [ ${#str} -eq 0 ] && echo 1 || echo 0
# [ `expr length $str` -eq 0 ] && echo 1 || echo 0
# [ `echo $str | wc -L ` -eq 0 ] && echo 1 || echo 0
# [ `echo $str | awk '{print length}' ` -eq 0 ] && echo 1 || echo 0
如果将函数放在独立的文件中,被脚本加载使用,要使用source或"."
在函数内部使用local定义局部变量,变量离开函数后消失
在函数执行的时候,函数名后面不要跟括号
cat >>/etc/functions << - EOF #EOF可以使用Tab而不用顶格
oldboy()
{
}
EOF
echo -e “\E[1;31m \E[4m blueicex \E[0m”
echo -e “\033[1;31m \033[4m blueicex \033[0m”
0关闭所有属性
[1加粗m
1高亮m
4下划线m
5闪烁m
7反显m
8消隐m
30-37前景色m
40-47背景色m
#!/bin/bash
RED="\E[1;31m"
CREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
REST="\E[0m"
read -p "pls select a number 1,2,3,4" num
case "$num" in
1)
echo -e "${RED}RED${REST}"
;;
2)
echo -e "${YELLOW}YELLOW${REST}"
;;
3)
echo -e "${BLUE}BLUE${REST}"
;;
4)
echo -e "${CREEN}RED${CREEN}"
;;
*)
echo "must be 1,2,3,4"
esac
优化版
#!/bin/bash
RED="\E[1;31m"
CREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
REST="\E[0m"
function usage(){
echo "$0 :{1|2|3|4}"
exit 1
}
function menu(){
cat <<END
1.......
2......
3......
4......
END
}
function chose()
{
read -p "pls select a number 1,2,3,4" num
case "$num" in
1)
echo -e "${RED}RED${REST}
;;
2)
echo -e "${YELLOW}YELLOW${REST}
;;
3)
echo -e "${BLUE}BLUE${REST}
;;
4)
echo -e "${CREEN}RED${CREEN}
;;
*)
usage;
esac
}
function main()
{
menu;
chose;
}
main;
#!/bin/bash
RED="\E[1;31m"
CREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
PINK="\E[1;35m"
REST="\E[0m"
if [ $# -ne 2] then
echo "$0 args is two:content color{red|yellow|green|blue|pink}"
exit 1
fi
case "$2" in
red|RED)
echo -e ${RED}$1${REST}
;;
blue|BLUE)
echo -e ${BLUE}$1${REST}
;;
green|GEEN)
echo -e ${GREEN}$1${REST}
;;
yellow|YELLOW)
echo -e ${YELLOW}$1${REST}
;;
pink|PINK)
echo -e ${PINK}$1${REST}
;;
esac
#!/bin/bash
RED="\E[1;31m"
CREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
PINK="\E[1;35m"
REST="\E[0m"
function pushcolor()
{
if [ $# -ne 2 ] then
echo "$0 args is two:content color{red|yellow|green|blue|pink}"
exit 1
fi
case "$2" in
red|RED)
echo -e ${RED}$1${REST}
;;
blue|BLUE)
echo -e ${BLUE}$1${REST}
;;
green|GEEN)
echo -e ${GREEN}$1${REST}
;;
yellow|YELLOW)
echo -e ${YELLOW}$1${REST}
;;
pink|PINK)
echo -e ${PINK}$1${REST}
;;
esac
}
pushcolor "blueicex" red
#!/bin/bash
RED="\E[1;31m"
CREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
PINK="\E[1;35m"
REST="\E[0m"
function pushcolor()
{
if [ $# -ne 2 ] then
echo "$0 args is two:content color{red|yellow|green|blue|pink}"
exit 1
fi
case "$2" in
red|RED)
echo -e ${RED}$1${REST}
;;
blue|BLUE)
echo -e ${BLUE}$1${REST}
;;
green|GEEN)
echo -e ${GREEN}$1${REST}
;;
yellow|YELLOW)
echo -e ${YELLOW}$1${REST}
;;
pink|PINK)
echo -e ${PINK}$1${REST}
;;
esac
}
function main()
{
pushcolor $1 $2 pushcolor $*
}
main $*
echo -e "\E[40;37m value \E0m"
\E可以用\33代替
65.rsync
# rsync --daemon
# netstat -tnulp | grep 873
# pkill rsync
#!/bin/bash
. /etc/init.d/functions
REVALUE=0
killproc=0
startproc=0
if [ $# -ne 1 ] ; then
echo "$0:{start:stop:restart}";
fi
case "$1" in
"start"|"START")
if [ `netstat -tnulp|grep 8730|wc -l` -ge 1 ] ;then
action "$0 already started" /bin/false
exit 0
fi
/usr/local/rsync/bin/rsync --daemon
sleep 2
$REVALUE = $?
if [ $REVALUE -eq 0 ] ; then
action "rsycn is started" /bin/true
exit 1
fi
if [ $REVALUE -nq 0 ] ; then
action "rsycn start faile" /bin/false
exit 0
fi
;;
"stop"|"STOP")
if [ `netstat -tnulp|grep 8730|wc -l` -ge 1 ] ;then
killall rsync
sleep 2
action "$0 already stoped" /bin/true
exit 1
fi
action "rysnc is started" /bin/true
exit 1
;;
"restart"|"RESTART")
if [ `netstat -tnulp|grep 8730|wc -l` -ge 1 ] ;then
killall rsync
sleep 2
killproc=`netstat -tnulp|grep 8730|wc -l`
fi
/usr/local/rsync/bin/rsync --daemon
sleep 2
startproc=`netstat -tnulp|grep 8730|wc -l`
if [ $killproc -eq 0 -a $startproc -ge 1 ] ; then
action "rsycn is already restart" /bin/true
exit 1
fi
exit 0
;;
*)
echo "$0:{start:stop:restart}"
exit 0
;;
esac
需要将rsycnd脚本放在/etc/init.d/下,否则无效
chkconfig --list rsycnd
chkconfig --add rsycnd
function name(){}
function name{}
name(){}
72.1.return是退出函数,exit是退出脚本
72.2.如果函数放在脚本文件里,要使用source和.
72.3.使用local定义局部变量
72.4. 函数实例
#!/bin/bash
function usage()
{
echo $"usage:$0 url";
exit 1;
}
function check_url()
{
wget --spider -q -o /dev/null --tries=1 -T 5 $1
if [ $? -eq 0 ]
then
echo "$1 is yes"
else
echo "$1 is no"
fi
}
function main()
{
if [ $# -ne 1 ]
then
usage
fi
check_url $1
}
main $*
#!/bin/bash
. /etc/init.d/functions
function usage()
{
echo $"usage:$0 url";
exit 1;
}
function check_url()
{
wget --spider -q -o /dev/null --tries=1 -T 5 $1
if [ $? -eq 0 ]
then
action "$1 is yes" /bin/true
else
action "$1 is no" /bin/false
fi
}
function main()
{
if [ $# -ne 1 ]
then
usage
fi
check_url $1
}
main $*
`awk '{print "wget https://github.com/blueicex/blueice1980/tree/master/yumsource/"$1}' yumfiles `
:nohl
#!/bin/bash
function mod_yum()
{
echo "mod_yum"
if [[ -d /etc/yum.repos.d ]]
then
mkdir /etc/yum.repos.d &>/dev/null
fi
`awk '{print "wget https://github.com/blueicex/blueice1980/tree/master/yumsource/"$1}' yumfiles`
}
function close_selinux()
{
echo "close_selinux"
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' -n /etc/selinux/config
grep 'SELINUX=disabled' /etc/selinux/config
setenforce 0 &>/dev/null
getenforce
}
function close_firewalld()
{
echo "close_firewalld"
iptables -F
systemctl stop firewalld
}
function lestest_service()
{
echo "least_service"
}
function adduser()
{
echo "adduser"
if [ `grep -w "blueicex" /etc/passwd|wc -l` -lt 1 ]
then
useradd blueicex
echo blueicex|passwd --stdin blueicex
\cp /etc/sudoers /etc/sudoers.bak
echo "blueicex ALL=(ALL) NOPASSWD:ALL " >> /etc/sudoers
tail -l /etc/sudoers
visudo -c
fi
}
function charset()
{
echo "charset"
echo 'LANG="zh_CN.UTF-8"' > /etc/sysconfig/i18n
source /etc/sysconfig/i18n
}
function time_sync()
{
echo "timesysnc"
cron=/var/spool/cron/root
if [[ `grep -w "ntpdate" $cron|wc -l` -lt 1 ]]
then
echo "*/5 * * * * /usr/sbin/ntpdate time.nist.gov >/dev/null" >> $cron
crontab -l
fi
}
function com_line_set()
{
echo "com_line_set"
}
function open_file_set()
{
echo "open_file_set"
if [[ `grep 65535 /etc/security/limits.conf|wc -l` -lt 1 ]]
then
echo '* - nofile 65535 ' >>/etc/security/limits.conf
tail -l /etc/security/limits.conf
fi
}
function set_kernel()
{
echo "set_kernel"
if [[ `grep kenel_flag /etc/sysctl.conf|wc -l` -lt 1 ]]
then
cat >>/etc/sysctl.conf << EOF
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 1
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait =120
EOF
fi
}
function init_ssh()
{
echo "init_ssh"
\cp /etc/ssh/sshd_config /etc/ssh/sshd_config.`date +"%Y-%m-%d_%H-%M-%S"`
sed -i -e 's%#Port 22%Port 51111%' -e 's%#PermitRootLogin yes%PermitRootLogin no%' -e 's%#PermitEmptyPasswords no%PermitEmptyPasswords no%' /etc/ssh/sshd_config
sed -i -e 's%#UseDNS yes%UseDNS no%' /etc/ssh/sshd_config
systemctl restart sshd
}
function update_linux()
{
echo "update_linux"
yum update -y
yum install nmap tree dos2unix nc -y
}
main()
{
#mod_yum
close_selinux
close_firewalld
adduser
charset
time_sync
com_line_set
set_kernel
init_ssh
update_linux
}
main
[ -f /etc/init.d/functions ] && ./etc/init.d/functions || exit 1
-eq 是关系运算符号,不能用于比较字符相等
\换行操作符
read -p "...." ans
case "$ans" in
1) //字符串比较不加""
;;
7|9)
;;
[3-6])
;;
*)
;;
esac
#!/bin/bash
FILEPATH=/blueicex/users
. /etc/init.d/functions
[ ! -f $FILEPATH ] && touch $FILEPATH
function usage()
{
echo `basename $0` add del search
}
if [ $UID -ne 0 ]
then
{
echo "Operation must supper user!"
exit 1
}
fi
if [ $# -ne 2 ]
then
{
usage
exit 1
}
fi
case "$1" in
-a|add)
shift
if grep "^$1$" $FILEPATH >/dev/null 2>&1
then
action "$1 is alreay exist" /bin/false
exit 1
else
chattr -i $FILEPATH
cp $FILEPATH $FILEPATH.`date +%F%T`
echo "$1" >> $FILEPATH
[ $? -eq 0 ] && action "Add $1 succees" /bin/true
chattr +i $FILEPATH
exit 0
fi
;;
-d|del|delete)
shift
if [ `grep "^$1$" $FILEPATH | wc -l` -lt 1 ]
then
action "$1 user not exist" /bin/false
exit 1
else
echo $1
chattr -i $FILEPATH
cp $FILEPATH $FILEPATH.`date +%F%T`
sed -i '/^${1}$/d' $FILEPATH
[ $? -eq 0 ] && action "delete user success" /bin/true
chattr +i $FILEPATH
exit 0
fi
;;
-s|search)
shift
if [ `grep -w "$1" $FILEPATH | wc -l` -lt 1 ]
then
action "$1 is not exist " /bin/false
else
action "$1 is exist " /bin/true
fi
;;
*)
usage
exit 0
;;
esac
grep -w 'blueicex' /etc/passwd
grep '^blueicex$' /etc/passwd
grep '/blueicex/b' /etc/passwd
while <condition>
do
command
done
until <condition>
do
command
done
while true/[ 1 ]
do
usleep 20000 //微秒
uptime //Tell how long the system has been running
done
> sh /.../.sh& //后台运行命令 nohup/.../.sh & //nohup - run a
> command immune to hangups, with output to a non-tty
#新建一个叫yourname的session
screen -S yourname
#列出当前所有的session
screen -ls
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
screen -wipe命令清除该会话
暂停脚本运行
ctrl+z
关闭执行的脚本
kill %n
i=12
while ((i>0))
do
echo "$i"
((i--))
done
i=12
while [[ $i>0 ]]
do
echo "$i"
((i--))
done
i=12
while [ $i -gt 0 ]
do
echo "$i"
((i--))
done
i=12
utile [ $i -gt 0 ]
do
echo "$i"
((i--))
done
#!/bin/bash
total=0
export LANG="zh_CN.UTF-8"
NUM=$((RANDOM%6))
readnum()
{
read -p "please input number" number
exper $number +1 &> /dev/null
if[ $? -ne 0 ]
then
echo "please input number"
readnum
if
}
guess()
{
((total++))
if[ $number -eq $NUM ]
then
if[ $total -le 3 ]
then
fi
}
main()
{
readnum;
while true
do
gusee
done
}
main
85.1
sum=100
i=0.15
while((sum>=i)) //不加¥
do
((sum=sum-i))
[ $sum -lt $i ] && break;
echo "send message left $sum"
done
echo "money is not enough:$sum"
85.2
sum=100
i=0.15
while ((sum>=i))
do
((sum=sum-i))
[ $sum -lt $i ] && {
echo "send message left $sum,money is not enough"
break;
}
done
85.3
sum=15
msg_count=0
msg_fee=1.5
menu()
{
cat <<END
1.recharge
2.sendmessage
3.quit
END
recharge()
{
read -p "please input charge number" number
expr $number+1 &>/dev/null
[ $? -ne 0 ] && echo "input charge number must is int" || { ((sum=sum+number)) echo "current sum is $sum"}
}
sendmessage()
{
if [ $sum -lt $msg_fee ]
then
printf "remainder fee is not enough $sum\n"
else
while true
do
read -p "please input message content" messag
((sum=sum-msg_fee))
printf "send message success\n"
if [ $sum -lt msg_fee ]
then
printf " remainder fee is not enought $sum\n"
return 1
fi
done
fi
}
main(){
while [[ 1 ]]
do
menu
read -p "please input num select:" select
case "$select" in
1)
recharge()
;;
2)
sendmessage()
;;
3)
exit 1
;;
*)
printf "select is wrong. must is {1|2|3}\n"
;;
esac
done
}
main
#!/bin/bash
. /etc/init.d/functions
if [ $# -ne 1] then
action $"useage $0 need url" /bin/false
exit
fi
while true
do
if [ `curl -o /dev/null --connect-time 5 -s -w "%{http_code}" $1 | egrep -w "200|300|" | wc -l ` -ne 1 ]
then
action "$1 is error" /bin/false
mail -s "$1 is error" [email protected]
else
action "$1 is ok " /bin/true
fi
sleep 5
done
#!/bin/bash
. /etc/init.d/functions
check_cout=0
//数组定义方式
url_list=(
http://192.168.3.62
http://45.40.199.217
http://www.baidu.com
)
function wait(){
echo "3 second late check begin"
for ((i=0;i<3;i++))
do
echo -n ".";sleep 1;
done
echo
}
function check_url()
{
wait
for ((i=0; i<`echo ${#url_list[*]}`; i++)) //数组访问方式和取得数组大小,${url_list[*]}取得数组所有元素
do
wget -o /dev/null --tries=1 -T 3 --spider ${url_list[$i]} >/dev/null 2>&1
if [ $? -eq 0 ]
then
action "${url_list[$i]}" /bin/true
else
action "${url_list[$i]}" /bin/false
fi
done
((check_cout++))
}
main(){
while true
do
check_url
echo "------check count: ${check_count}----------"
sleep 10
done
}
main
88.1
#!/bin/bash
. /etc/init.d/functions
sum=0
exec < $1
while read line
do
size=`echo $line | awk '{print $10}'`
expr $size+1
if [ $? -ne 0 ]
then
continue
fi
((sum=$sum+$size))
done
echo "${1} :total:${sum}bytes=`echo $((sum/1024))`KB"
88.2
awk '{print $10}' access_log-2018608 | grep -v "-" | awk '{sum+=$1} END {print sum"KB"}'
89.1
exec<file
sum=0
while read line
do
cmd
done
89.2
cat FILE_PATH | while read line
do
cmd
done
89.3
while read line
do
cmd
done<file
while read line
do
echo $line
done<$1
91.1
for i in valuse
do
command
done
in valuse可以省略,相当于in $@
91.2
for in in values
do
if [ condition1 ] && [ condition2 } && [ condition 3]
command
else
command
fi
done
91.3
for((begin;condition;end|))
do
command
done
91.4
for num in 1 2 4 5 6
do
echo $num
done
91.5
function main()
{
for arg in $@
do
echo $arg
done
}
91.6
#echo {3..1}
#4 3 2 1
echo [1-4]
[1-4]
#echo -e [1-4]
[1-4]
91.7
for in `seq 1 5 `/`ls`
do
command
done
92.1
#!/bin/bash
cd /test
for filename in `ls | grep 'txt$' `
do
mv $filename `echo $flilename | cut -d "." -f1`.gif
done
92.2
rename "gif" "txt" *.gif
rename "_finish" "" *.jpg //去除文件名中共同的部分
92.3
#!/bin/bash
for file in `ls *.jpg`
do
mv $file `echo $file | sed 's/_finish//g'`
done
92.4
ls | awk -F '.' ' { if($2=="txt") {print "mv " $0 " "$1"blueicex.gif"} } ' | bash
chkconfig --list | grep 3:on
94.1
LANG=en
for closeprocess in 'chkconfig --list | grep 3:on | awk '{print $1}''
do
chkconfig --level 3 $closeprocess off
done
for startprocess in sshd crond network
do
chkconfig --level 3 $startprocess on
done
chkconfig --list | grep 3:on
94.2
LANG=en
for process in `chkconfig --list | grep 3:on | awk ' { print $1 } ' | grep -vE 'sshd|httpd|crond'
do
chkconfig $process off
done
94.3
chkconfig --list | grep 3:on |grep -vE 'sshd|httpd|crond' | awk ' { print "chkconfig " $1 " off"} ' | bash =========chkconfig --list | egrep -v 'sshd|httpd|crond' | awk ' { print "chkconfig " $1 " off"} ' | bash
#!/bin/bash
PATH="/usr/bin/":$PATH
DBBKPATH=/blueicex/dbback
DBUSER=root #未加""
DBPASSWD=blueicex
SOCKET=/var/lib/mysql/mysql.sock
LOGINCMD="mysql -u$DBUSER -p$DBPASSWD -S $SOCKET"
DUMPCMD="mysqldump -u$DBUSER -p$DBPASSWD -S $SOCKET"
[ ! -d "$DBBKPATH" ] && mkdir $DBBKPATH
for dbname in `$LOGINCMD -e "show databases;" | sed "1,2d" | egrep -v "mysql|schema"`
do
$DUMPCMD $dbname | gzip >$DBBKPATH/${dbname}_$(date +%F).sql.gz
done
#!/bin/bash
DBUSER=root
DBPASSWD=blueicex
SOCKET="/var/lib/mysql/mysql.sock"
LOGINCMD="mysql -u$DBUSER -p$DBPASSWD -S $SOCKET"
for dbname in "gege" "liuzexuan"
do
$LOGINCMD -e "create database if not exists $dbname;"
done
$LOGINCMD -e "show databases;"
# cat dbtxt
blueicex male 38 basketball
gege female 34 eatmeat
liuzexuan female 7 watchTV
#!/bin/bash
DBUSER=root
DBPASSWD=blueicex
SOCKET="/var/lib/mysql/mysql.sock"
LOGINCMD="mysql -u$DBUSER -p$DBPASSWD -S $SOCKET"
awk ‘BEGIN{name='';age='';sex='';favor='';
————Blueicex 2020/2/5 9:50 [email protected]