贫僧工作3年3月有余,行事开发。察shell编程,下方实例与开发者差强人意。
1:文件开头#!/bin/sh
2:打印里面的变量echo “${name}”
4:函数
function 函数名(){
可以没返回,返回则必须是数字,外面程序通过$?获取
return 18
}
传参利用位置变量 1, 2,$$-pid,$*-参数数组,$@-参数数组,$#-参数个数
5:if ,while ,case,for
if[];then …
elif[];then …
else ….
fi
if判断语句的写法
if [ ]
then
echo “”
elif[ ]
then
echo””
else
echo””
fi
if语句的写法
if[ ]
then
echo””
else
echo “”
fi
case语句的写法
case
strin正则1)命令序列1;;正则2)命令序列2;;∗)默认命令序列3esacwhile循环的写法while空格[];doecho“”donewhile循环的写法while空格[]doecho””donefor循环第一种for((i=1;
i <=100 ;i++));do
echo
idonefor((i=1;
i <=100 ;i++))
do
echo
idone第二种foriin
(seq 1 100 );do
echo
idoneforxinonetwothreefourdo…echonumber
x
done
实例
对目录中的文件做for 循环
!/bin/bash
for x in /var/log/*
do
echo
basename$xislivingdone
x 获取绝对路径文件名,使用basename 除去文件名的路径信息
没有文件路径前缀的写法:for x in * :含义表示在当前工作目录中循环
7:[ -f *.txt ]:判断是否是同一个文件
if判断的参数
-a 文件存在为真
-d 文件存在且是目录
-e 文件存在则为真
-f 文件存在且是普通文件为真
-h 文件是一个符号联接文件为真
-r 文件存在且是可读
-s 文件存在且大小不是0 if [ -s filename]
-w 文件存在且是可写的
-x 文件存在,且是可执行的
-l 文件存在,且是符号链接
-s 文件存在,且是套接字
-z [ -z STRING] “STRING”字符串长度为0则为真
-n STING 长度为非零为真
8: 判断是否存在/etc/shadow文件
[-f “/etc/shadow”]
9:判断是否存在/etc/shadow,若存在打印&&后面的数据
[-f “/etc/shadow”] && echo ”this is file shadow “
10:判断是可读文件
maildirs = /var/spool/maildirs/james
[-r “$maildirs”]
11: 选择语句的写法
select var in “xx” “ccs” “ssd” ;do
break
done
12:find logdir_bak* -type d -mtime +30| xargs -i rm -rf {}
-i 同 -I用法相同
参数xargs -i {} 意思是把find到的内容一行一行的作为入参,传给rm执行.
xargs -t :先打印命令在执行
13:-mtime n
这里n有带+ 的,带-号的,不带符号的。
带+号:找n天前所有文件 n=+1 (算今天在内15天之前的文件)
带-号:从今天到之前的n天的日志。(包括今天)
不带符号指:仅n天那一天的记录
23:find -type 查找某一类型的文件
-type d 目录
-type f 普通文件
-size 文件大小
+0 表示大于0的文件
24: 调试语法 sh -n copy.sh
25: 跟踪运行 sh -vx copy.sh
26:tar 使用
-cvf 打包
tar -cvf 打包后包名.tar -C路径 :打指定路径下的包
-z 压缩
-xvf 解包
将过去24小时修改过的文件打包
tar -zvcf xxx.tar.gz \ find .-mtime -1 -type f -print
tar cvf logdir_bak
DATESTR.tar∗compress−flogdirbak
{DATESTR}.tar
27:mv /dev/null
在linux中,/dev/null 或null 是一个特殊的文件,所有写入他的数据都会被清空
实际并不能阻止数据恢复软件重新把他还原。
28;在脚本中执行脚本3中方法
source first.sh 或 .first sh 或 sh first.sh
29 : 脚本里面的函数
#!/bin/bash
add(){
a=
1;b=
2;
z=’expr
a+
b ‘;
echo “is sum $z”
}
execute add()
add 1 2
35:shell 里面的变量自增
1;i=expr $i + 1
;
2:let i+=1;
3:((i++));
4:i=
[
i + 1 ]
5:i =
37:计算当前目录下文件的个数(不包括子文件)
ls -l |grep “^-“|wc -l
count=ls -l |grep "^-"|wc -l
39:shell的内建命令
shift 的用法
比如shift3 ,表示原来的
4现在变成
1 ,原来的
5现在变成
2,原来的
1,
2,
3丢弃。
0不动。仅shift表示shift 1
0:本程序的名称(不是绝对路径名称)
1-
9行
* 表示这个程序的所有参数(不超过9个)。
例如:“
1
2
$$ 这个程序的PID(程序运行在当前的进程ID)
$! 上一个后台命令对应的进程号
$? 执行上一个指令的返回值(0表示没有错)
$- 显示shell使用的当前选项。与set命令的功能相同。
$@ 跟$*类似,但是可以当做数组处理。
例如: “$1” “$2” “$3” 参数之间是一个独立的个体
; 命令分隔符,用来在一行里面执行多个命令
; ; case语句终止执行功能
“” 双引号里面的内容解析后输出
” 单引号不解析,原样输出
“ 倒引号,倒引号括住的变量代表的是命令,按照命令执行,获取执行的返回值。
$() 小括号和反引号的作用是一样的
\ 转译字符
/命令替换
: 空命令,bash内建命令相当于真值
() 对一串命令重新开始一个shell执行,最后一个命令不用分号
(()) :((a++)) (( a= 10 ))
{} 对一串命令在当前shell 执行,最后的命令要用分号
[[]]:允许使用|| 和&& 如 if[[ $ak >5 || $ak <9 ]]
内建指令
~ 账户的HOME 目录,如:~/bin
~+ 当前的工作目录,相当于pwd
~- 上次的工作目录.是上次不是上层奥
. 当前工作目录
. . 上层工作目录
文件名称使用.开头就是特俗档案。如.profile
ls a[! 0-9]: 排除显示a0,a1,a2,…a9
**代表次方运算
[ $# -ne 2 ]//参数的个数不等于2
rm -r 200[1234] :代表删除2001,2002,2003,2004
&& :逻辑符号
& :单个&, 放在完整指令的最后端,表示将指令放入后台工作
\< … > 单字边界
40:读取文件的数据,并将它存入到变量
var = $(cat name.txt)
41: shell 连接sqlplus 这么调用
sqlplus -s 用户名/口令@实例名<
!/bin/sh
echo “
0is:"
0 >>testss.txt
echo “
1is:"
1 >>testss.txt
echo “
2is:"
2 >>testss.txt
if((
2==“1”));thenecho“is1:”
2 >>testss.txt
else
echo “is not 1,is “$2 >> testss.txt
fi
*******************************
echo “path is $sourcepath” >>testss.txt
ls -l |grep “^-“|wc -l >>testss.txt
count=ls -l |grep "^-"|wc -l
echo
countif((
count == “0” ));then
echo “ddd” >>testss.txt
else
echo “dddccc” >>testss.txt
echo “over ” >>testss.txt
echo “over”
fi
50 :java 重定向日志,这个重定向可以输出System.out.println()输出的内容
下例子也是输出shell脚本的返回值,Java得到的是shell 里面echo 的返回值,如果echo >>xx.log
那么就不能给java程序返回值。java程序获得的仅是最后一个echo 的返回值,且不是重定向的echo
PrintStream out = System.out;
PrintStream ps = null;
try {
ps = new PrintStream(“/artery/domains/logs_bak/javalog_t.txt”);
} catch (FileNotFoundException e2) {
}
System.setOut(ps);
System.out.println("start**********************");
Process pcs = null;
BufferedReader bufferedReader = null;
pcs = Runtime.getRuntime().exec(cmdrr);
String result = null;
if (pcs != null) {
bufferedReader = new BufferedReader(new InputStreamReader(
pcs.getInputStream()), 1024);
String lines = null;
try {
while (bufferedReader != null
&& (lines = bufferedReader.readLine()) != null) {
result = lines;
}
if ("0".equals(result)) {
System.out.println("sucess");
} else {
System.out.println("faild ,errorcode is :" + result);
}
System.out.println("程序运行完毕,请查看日志");
System.setOut(out);
52:/dev/null
清空目录logs下面文件的内容,保持文件名不变,但文件大小为0
cd $SOURCEPATH
for i in find . -type f
;do cat /dev/null >
i;doneecho“ok∗∗∗∗∗∗∗∗∗∗∗∗∗”>>
BAKLOG
53:修改文件,或文件夹的读写执行权限
chmod 777 文件名称
chmod 000 文件名称 <–! 不具有任何权限>
所有者读,写,执行 用1代表是,0代表否
用户组读,写,执行
其他读,写,执行
例如:所有者:111 用户组:100 其他:000
111 100 000 都转为2进制 ;740
其中参数
-R:递归的改变这个文件目录下面的所有文件,包括目录和目录里面的文件。如:chmod -R 777 /home/user/sdfsa/
54 :移动文件的时候,目标文件夹如果没有权限,文件移动会失败,但是shell得到的执行mv 命令的返回值是0
55:远程拷贝文件,
scp ,它使用的远程协议是ssh1,
本地到远程 :scp 文件名1 远程用户名@IP地址:文件名2
远程到本地 :scp 远程用户名@IP地址:文件名1 文件名2
将本地考到远程 :指定目录方式 scp /home/test.tar root@IP:/home/adm/
参数:
-r :指定是目录 ,后面跟绝对目录名
-p :保留原文件的修改时间,访问时间,和访问权限
-1 :强制使用ssh1协议
-2 :强制使用ssh2协议
56:在shift命令执行前, 1变量的值在shift命令执行之后就变为 2的值。
57:修改文件的创建,访问时间。
修改时间为今日
touch file1 若file1存在,则把文件修改为今日创建,若不存在,则创建。
touch file1 file2
修改时间为指定日,无年默认为当前年
touch -c -m -t 05061803 file1
将file2 的时间记录修改与file1一样
touch -r file1 file2
时间Time 格式 MMDDhhmm[YY] /01 -12 /01-31/00-23/00-59
-t [[CC]YY]MMDDhhmm[.SS]
注意:在给文件转换年月日的时候,如果本月仅30天,没有31天,赋值的时候强制0931,则认为是0930+1 ,也就是下个月第一天1001.
58: 有些linux环境不支持for(()) ,不支持seq ,若要使用for循环,使用in 是可以的。
59: shell 连接oracle
sqlplus / as sysdba@orcl <
!/bin/sh
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
echo “Start check sql.”
sqlplus -S artery/artery <
!/bin/sh
serverIp=10.1.32.1
ftpUser=ebicproj
ftpPwd=ebic135338
cd /artery/production/artery-1.0/conf
rm -f esscapi_sm_normal_*.log
if [ -d /artery/update/20151028 ]
then echo “OK”
else mkdir -p /artery/update/20151028;
fi
cd /artery/update/20151028
mv bak_app_log.sh bak_app_log.sh1
ftp -n <
!bin/bash
source xxx.sh
75:取消变量
unset 变量名(不加$)
76:变量赋值
普通字符串:
变量名=value
变量名=’value’ 单引号,原样输出(有变量就输出变量名)
变量名=”value” 双引号,取变量结果,命令的结果输出
命令变量:
变量名=value
命令赋值
变量名=$(value)命令赋值
77:输入文件内容
cat > b.txt 回车
(输入:)
ddfj
ffll
ctrl+c/ctrl +d
78:awk使用shell 中的变量
awk ‘BEGIN {print “’${name}’”}’ //
79:日期格式
echo date +%F
80:执行shell脚本传参
sh test.sh {a..z}
sh test.sh {a..z}
81:
@和
*
set – i am “niehw”
for i in “
@";doecho"
i”;done
@:传给shell的所有参数,且每个参数独立
*: 传给shell的所有参数,且所有参数是一个整体。
82:for 循环去掉in
for i ;do echo
i;done;相当于i在
@
83:shift
移动位置变量
把
(n)=
(n+1) ,也就是参数向前移动一个。
84:只能有一个进程启动这个脚本
!/bin/sh
pidpath=/home/nie_test/temp/a.pid
if[ -f “$pidpath” ] ;then
kill -USER2 cat $pidpath
rm -f
pidpathfiecho
>
pidpath
sleep 300
85:wc 计算单词数
-c:按照字节计算
-m:按照字符计算
-l: 按照行数计算
-L:最长的行,的长度
86:路径变量赋值
value?"nodefind",如果value是空,或者未定义,显示:
value:nodefind
${vlaue:+word},value存在,返回word,否则,返回null
87:time 其他命令集合
测试命令执行的时间
time wc -l
88:数值计算
(()):整数
$[ ]
let { let i=i+8 }
expr (加)(还有其他特殊用法比较)
bc(只有它计算的是小数)(可以做进制转换)
计算符号:
++ ,–,+ ,- ,!,~(位取反)
* ,/, %,
<,<= ,>,>=,
== ,!=
,<<
&(位的and)
^(位的异或)
| (位的或)
&&逻辑and
|| 逻辑或
?:(条件表达式)
* 幂(100* 5)
89:整数比较
-ge :大于等于
-gt:大于
-ne: 不等于
-eq:等于
-le:小于等于
-lt:小于
字符串比较:
= 等于 变量是否为空 [ -z
str]或["
str” =”” ]
!= 不等于
if [$? -ne 0 ]
then
echo ” ”
else
echo ” ”
fi
90:expr的比较
expr “
1":"dffl.zip"//
1的值是否匹配dffl.zip,如果匹配则为真
91:shell 里面没有判断整数的函数
思想
expr 1+1 &>/dev/dull
if [? == 0 ]
then
echo “是整数”
fi
95:调用脚本里面的方法
!/bin/sh
menu( ){
cat << EOF
1、你好
2、我好
EOF
}
menu
99:[] 和[[]] 的逻辑操作符
在[ ] 中使用的逻辑操作符 在[[] ] 中使用的逻辑操作符
说明
-a && and
-o || 或
! ! 非
实例:
错误实例:[ -f “filepath1" && -f "fialepath2” ]&& echo 0 || echo 1
正确实例:
[ -f “
filepath1"−a−f"
fialepath2” ]&& echo 0 || echo 1
比较字符串内容
[ -n “
f1"−a"
f1”=”f2” ]&&echo 0 || echo 1
“f1"="
f2”:比较字符串内容字符串比较长度[−n“
f1" -a "{#f1}”=”{#f2}” ] && echo 0 || echo 1
整数比较用-eq
100:判断不成立,执行一堆命令
[ 2 -ne 2 ] || {
echo “”
echo “”
exit 0
}
或者
[ 2 -ne 2 ] || {echo “”;echo “”;exit 1;}
101:查看WEB服务状态
nmap 127.0.0.1 -p 80 |grep open |wc -l
102:获取Http的返回码。模仿用户的方式
curl -I -s -w “{http_code}” -o /dev/null 10.0.0.7
103:爬一个网站,模范用户的方式
wget –spider –timeout=10 –tries=2 10.0.07
104:显示执行成功的样式
[ok]
action “runing success” /bin/true
105:shell的函数
函数名(){
指令
return n
}
或者规范写法
function 函数名(){
指令
return n
}
对于传参来说:
函数格式不变,调用时候在后面直接加参数
function 函数名(){
指令
1,
2,3
return n
}
函数名1,
2,
3
106:if ,while ,util 后面加的是shell命令,而不是表达式
!/bin/bash
dir=”/etc”
ls -l dir &> /dev/null
ret=?
if [
ret−eq0]thenecho“hell”elseecho“nigun”fiifls−l
dir & >/dev/null
then
echo “yes”
else
echo “no”
fi
!/bin/bash
count=0
while [
count−le100]docount=
[$count + 1]
done
shell里面“;” ,就相当于回车
!/bin/bash
count=0
until ![
count−le100]doecho
count
count=
[
<script type="math/tex" id="MathJax-Element-53">[</script>count + 1]
done
!/bin/bash
address=’localhost’
while [ true ]
do
while ping $address & >/dev/null
do
sleep 1
done
until ping
do
echo “ok”
done
done
110:read,declare,nohup,crontab,jps
read -s -p “username:” -t 3
-s:隐藏输入
-p:打印提示
-t :超时时间
declare -i num :生命num是整形
nohup xxx.sh >/dev/null 2>&1 &
crontab -e :编辑一个定时任务
-l:查看
* * * * *
分 时 日 月 周
* 就是不做限制
jps是去文件里面找的。
cat /tmp/hsperfdata_root