分类:
2017-09-18 19:34:18
原文地址:shell编程-周朝剑 作者:leiminghany
==============1 文件管理及权限=============
shell的类型ash、bash(默认)、ksh、csh、tcsh
echo $shell
/bin/csh
ls -l 的解释(类型、权限、硬链接数、用户名、用户组、大小、最近修改时间、文件名)
文件类型dlbcpsf(目录、连接、二进制块、字符、管道、编程用得,普通文件)
chmod [who] operator [permission] filename
who (u拥有者、g所属组、o其他、a所有)operator(+-=)permission(rwxs(setuid、s覆盖x用户如果执行这个文件时以这个身份来运
行、用于以普通用户来执行一些任务而无需用管理员身份登录)t(拥有者才能删))
chmod u=rwx,g+w,o+r myfile
chmod mode filename
mode r4w2x1
chmod 4744 myfile =u+s
chmod 6744 myfile =g+s
chmod 7744 myfile =o+t
chown [-R] owner myfile //-R表示递归
chown owner.group myfile
chown .group myfile //直接改变文件所属组
chgrp [-R] group myfile
umask 默认的用户文件的权限
022 -目录755-文件644
umask 000 //修改默认权限
cat /etc/profile; cat /home/vmlinux1/.bash_profile
-------------------
硬链接:磁盘上
软连接:存储地方;
ln -s myfile mylink //软连接类似快捷方式。大小很小。
----------------------
shell脚本
#!/bin/bash
#这是一个shell实例
printchar="hello,world"
echo $printchar
echo "leiminghany"
alias ll='ls -alh'
cat $HOME/.bashrc //别名的存放位置
ls `cat myfile` -al //命令的替换
nohup tar -czf myfile.tar.gz myfile & //后台运行,一个终端运行多个程序
jobs -l //查看后台运行的程序
ls -l|sort //管道,前面的输出作为后面命令的输入
重定向<>
sort
正则表达式进行模式匹配
特殊字符" ' ` \转义 ;一行运行多个命令 & () {} | <> $ # *?[]!
touch 'lei ming'
单引号忽略特殊字符
===========2 变量 引号 运算符============
本地变量
localtest="test"
echo $localtest
set //查看 exit后不存在了
readonly localtest
localtest="chinaitlab"
readonly //查看只读变量
上面指的是本地变量
环境变量用于所有用户和子进程中
export CHINAITLAB="shenzhen"
env //查看
export //查看
readonly CHINAITLAB
/etc/profile $HOME/.bash_profile
变量替换
${Variable name}
${Variable name:+value} 如果Variable设置,则显示value。否则为空
${Variable name:-value} 如果Variable未设置,则显示value,否则显示其值
${Variable name:?value} 如果未设置Variable,则显示错误信息value
${Variable name:=value} 如果未设置Variable,则设置为value并显示
变量清除
unset testvar
echo ${testvar}
readonly变量不可以unset
位置变量$0,$1....$9
parm文件中的内容如下
#!/bin/bash
#parm
echo "名字:$0"
echo "第1个位置: $1"
echo "第2个位置: $2"
echo "第3个位置: $#"
echo "第4个位置: $*"
echo "第5个位置: $$"
echo "第5个位置: $?"
运行命令如下
./parm A B C
标准变量
bash自己设置的在/etc/profile
EXINIT(vi初始参数) HOME IFS(分隔符) LOGNAME(登录名) MAIL(当前用户存储的邮箱位置) MAILCHECK(每隔多少秒检查新邮件)
MAILPATH TERM(终端类型) PATH TZ(时区) PS1(\U用户名\h主机名\w当前目录) PS2 PWD EDITOR SHELL MANPATH TERMINFO
set |grep EDITOR
EDITOR
特殊变量
$#(参数个数) $* $$(当前进程id) $!(后台最后的进程id) $@(同上) $-(同set命令) $?
echo $#
影响变量的命令
declare -f只显示函数名 -r创建制度变量 -x创建转出(export)变量 -i创建整数变量
export -- -f -n -p
readonly -- -f
set
shift[n] 移动位置变量
typeset=decalre
unset -- -f
引号 '(不解析) "(解析$ \ `) `(执行命令) \(转义)
echo -e "ert, $SHELL '\n* china`echo itlab` "
echo -e 'ert, $SHELL '\n* china`echo itlab` '
运算符
~反 <<左移 >>右移 &与 a^b异或 |或
逻辑: && || > == < !=
$[ 2+8 ]
$[ 2<<4 ]
let $count=$count+$chang
---------
[root@localhost mywork]# var=65
[root@localhost mywork]# let var +=4
bash: let: +=4: syntax error: operand expected (error token is "+=4")
[root@localhost mywork]# let var+=4
[root@localhost mywork]# echo $var
69
[root@localhost mywork]#
---------
$[ base#n ] #base进制
echo $[ 10#8+1 ]
运算符的优先级可用括号改变
=============3 shell的输入与输出==================
echo[option] string
-e 解析转义字符(\c回车不换行 \f \t \n)
-n 回车不换行
----------------------
#!/bin/bash
#readname
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo -e "your name is :\n$firstname $lastname"
---------------------------
read只有一个变量则将所有的输入赋给该变量,指导文件结束符或火车,如果是多个变量则按顺序赋给每个变量,按空格分开
cat myfile1 myfile2 myfile3
cat -v dos.txt //显示windows中控制符
less ls.txt //分页显示 类似与vi但只读
df -k|awk '{print $1}'|grep -v "Filesystem" //查看磁盘分区 -v求补
tee -a files /标准输出同时并保存到文件 -a表示追加,用于管道最后
文件的重定向
每个进程联系的三个文件标准输入0标准输出1标准错误2。用户可以使用的文件描述符3-9
command 1>filename //把标准输出重定向到一个新文件中
command >filename 2>&1 //将结果和错误都从定向到filename中,&1这里表示filename
command >>filename 2>&1 //&1表示输出1的地方
command
command << delimiter //从标准输入 直到delimiter分解符
command <&m //文件描述符m作为标准输入
command <&m //输出到文件描述符
command <&_ //关闭标准输入
cat >>term.txt <
slfdfsd 2>/dev/null //错误丢失 文件不保存
slfdfsd 2>error.txt //错误重定向
cat new.txt old.txt 1>out.txt 2>error //用于记录日志
cat new.txt old.txt 1>out.txt 2>&1
>abc.txt //创建0字节文件abc.txt
shell从左向右分析命令
exec command //重新启动一个shell 本shell的环境变量都会无效 但和文件描述符一起使用是除外
exec ./hello.sh //打开新的shell
#!/bin/bash
#exec
exec 3>&0 0
read line2
exec 0<&3
echo "$line1 $line2"
================控制流结构======================
#!/bin/bash
make /home/mywork/txt
cp *.txt /home/mywork/txt
rm -f *.txt
#!/bin/bash
#iftest
if [ 10 -lt 12 ]
then
echo "right"
fi
[1>0] test 1>0
man test
---------------------------
[root@localhost shell]# echo $i
[root@localhost shell]# i=2
[root@localhost shell]# echo $i
2
[root@localhost shell]# if test $i -lt 3
> then echo "$i is smaller than 3"
> fi
2 is smaller than 3
[root@localhost shell]#
[root@localhost shell]# case $i in
> 1) echo "a";;
> 2) echo "b";;
> *) echo "c";;
> esac
b
[root@localhost shell]#
[root@localhost shell]# for loop in 1 2 3
> do
> echo $loop
> sleep 5
> done
1
2
3
[root@localhost shell]#
------------------------
#!/bin/bash
#test
echo -n "imput your name :"
read NAME
if [ "$NAME" = "" ]
then echo "please input"
elif cp a.txt.bak a.txt ; then
echo "copy ok"
else
echo "you are $NAME `basename $0`:error file no exsited"
fi
#!/bin/bash
#caseselect
echo -n "input number:"
read NUM
case $NUM in
1) echo "you input 1";;
2) echo "you input 2";;
y|Y) echo "you imput $NUM";;
*) echo "`basename $0` biger!"> ;;
esac
#!/bin/bash
#until_mon
#监控分区
part=/backup
#得到磁盘使用的百分比
LOOK_OUT=`df |grep $part |awk '{print $5}' |sed `s/%//g``
echo $LOOK_OUT
until [ "$LOOK_OUT" -gt "90"]
do
echo "filesystem is nearly full" |mail root
LOOK_OUT=`df |grep $part |awk `{print $5}` |sed 's/%//g'`
sleep 36000 //每小时循环一次
done
nohup //后台运行。。检测磁盘
#!/bin/bash
#pr
#exec 3<&0 0<$1
while read line
do
echo ">$line">>link
done<$1
#exec 0<&3
break [n] //n是跳出循环的层数
#!/bin/bash
#breaktest
while : # 冒号表示永远为真
do
echo -n "enter number 1-5:"
read num
case $num in 1|2|3|4|5)
echo "right";;
*) echo "wrong"
break;;
esac
done
#!/bin/bash
#out
if cat $1>>/root/mydoc/shellbj.ln
then
echo "successful!"
else
echo"'basename $0':no such file!"
fi
#!/bin/bash
#breaktest
while :
do
echo -n "enter number 1-5:"
read num
case $num in 1|2|3|4|5)
echo "right";;
*)
echo -n "continue?"
read conti
case $conti in
y|yes|Y|Yes) continue;;
*) break;;
esac
esac
done
================文本过滤18:00===============
^只匹配行首
$只匹配行尾
*匹配0获多个字符
[]匹配字符获字符序列
\转义
.匹配任意单字符
pattern\{n\}
pattern\{n,\}
pattern\{n,m\}
^...1
^$ 空行
^.$ 一个字符的行
[0-9]
[s,S]
A\{2\}B
A\{2,\}B
A\{2,4\}B
使用正则表达式中的find命令
find pathname -options [-print -exec -ok]
man find
find ./ -name "*.txt" -print
find -perm 644 -print
find `pwd` -user root -print
find -nouser -print //用户已删除但其文件还存在,
find ./ -group itlab -print
find /var -mtime -5 -print //5天之内
find /var -mtime +3 -print //三天以前
find `pwd` -newer "myfile" ! -newer "myfile123" -print //比myfile新 比myfile123旧
find /etc -type d -print
find . -size +100000c -print //大于100000字节的文件
find . -size +10 -print //大于10块
find / -name "con.file" -depth -print //广度遍历
find . -type f -exec ls -l {} \; //显示详细的文件信息
find /var -name "*.log" -mtime +5 -ok rm{} \; //删除5天前的日志文件
find ./ -perm -7 -print |xargs chmod o-w
find ./ -type f -print |xargs file //xargs 解决参数溢出问题
grep [选项] 正则表达式[文件]
-c只输出匹配航的计数
-i不区分大小写
-h查找多文件时不显示文件名
-H显示文件名
-l查询多文件时只输出包含匹配字符的文件名
-n显示匹配的行及行号
-s不显示不存在或无匹配文本的错误信息
-v显示不包含匹配文本的所有行
grep "jenny" *.txt
grep "lei" *
grep "lei" * -c
grep -i "lei" *
grep "2004:1[0-9]" myfile
grep "^[^210] myfile //2 1 0开头的过滤掉
grep "H*P"
grep "[2-5][1-3][3-5]" myfile
grep "4\{2\}" myfile
grep命令类名
[[:upper:]] 等价于[A-Z]
[[:alnum:]] [0-9A-Za-z]
[[:lower:]] [a-z]
[[:space:]] 空格或tab
[[:digit:]] [0-9]
[[:alpha:]] [a-zA-Z]
awk //其实是一种编程语言
awk [-F filed-spearator] 'command' input-files
awk '{print $0}' a.txt|tee a.out
awk -F : '{print $0}' a.txt|tee a.out //冒号分割
[root@vmlinux1 mywork]# awk 'BEGIN {print "NO\tname\ttel\n---------------------------"}{print $1"\t"$2"\t"$3} END
{print"end!"}' c.txt
NO name tel
---------------------------
1 leman 13473868874
2 angle 13524654565
3 zhang 13356464655
end!
+//match more char
?//match single char
~为匹配 !~为不匹配
cat score.txt|awk '$0 ~/218.79.131.96/' //记录中匹配218.79.131.96的记录
[root@vmlinux1 ~]# cat c.txt|awk '$2 ~ /le/'|grep 3|wc -l
[root@vmlinux1 ~]# cat c.txt|awk '$2 !~ /le/'|grep 3|wc -l //不匹配
awk '{if($1=="218.79.131.96") print $0}' score.txt //awk 流控制
sed不与初始化文件打交道,操作的是一个副本
sed [选项] sed命令 输入文件
sed [选项] -f sed脚本文件 输入文件
sed 脚本文件 [选项] 输入文件
基本编辑命令 p = a\ i\ d c\ s r w q l {} n g y
sed -n 2p logs.txt
sed -n '1-4p' logs.txt //打印1-4行
sed -n '4,/los/p' logs.txt //从第四行开始匹配到los结束
sed -n '/^$/=' myfile //打印空行行号
sed -n -e '/^$/p' -e '/^$/=' myfile //打印空行行号和空行
sed -n '/chinaitlab/a shenzhen' logs //在chinaitlab后面加shenzhen
sed -n '/chinaitlab/c shenzhen' logs>logs.out //替换为深圳,并重定向到文件中
sed '1,2d' logs //第1,2行删除
sed s/chinaitlab/china/g' logs //chinaitlab全部替换为china
sed -n 's/chinaitlab/& hello /p' log //若匹配则在后面加上hello
合并与分割
sort [options] files
-c 测试是否分类
-m 合并两个分类文件
-u 删除所有复制行
-o 存储sort结果的输出文件名
-t 域分隔符
+n n为域号,使用此域号开始分类
n 指定分类是域上的数字分类项
-r 比较求逆
sort -c myfile
sort -u myfile //相同的行合并
sort -r myfile
sort -t "/" +2 myfile
uniq [option] files //去除或禁止重复
uniq -c file //显示重复次数,不临近的例外
uniq -d file //只打印重复的
uniq -u file //只打印不重复的
uniq -f 2 file //前2个域被忽略
awk '{print $1}' logs |sort |uniq -c //统计网络各IP访问量
其他分割 join split cut paste
split -10 ls_out.txt split //每10行分割后缀为split
============第六章 shell函数================
函数定义:
[function] 函数名()
{
...
}
-----函数与参数--------
#!/bin/bash
#hellofun
function hello()
{
echo "hello $1 today is `date`"
return 1
}
echo "go to function hello"
hello chinaitlab
echo $?
#返回的制不能赋值给变量
echo "return to main "
-----函数作为单一文件调用------
#!/bin/bash
#funfile
function hello()
{
echo "hello today is `date`"
return 1
}
#!/bin/bash
#funcuse
. funcfile
set
echo "use func file"
hello
unset hello
echo "after unset"
hello
echo "end"
------------
==========脚本参数传递============
#!/bin/bash
#opt2
usage()
{
echo "usage:`basename $0` filenames"
}
totalline=0
if [ $# -lt 2] then
usage
fi
while [ $# -ne 0 ]
do
line=`cat $1|wc -l`
echo "$1:${line}"
totalline=$[$totalline+$line]
shift
done
echo "----------"
echo "total:${totalline}"
------getopts---------
#!/bin/bash
#optgets
ALL=false
HELP=fase
FILE=false
VERBOSE=false
while getopts ahfvc: OPTION
do
case $OPTION in
a) ALL=ture
echo "ALL is $ALL"
;;
h)
HELP=ture
echo "HELP is $HELP"
;;
f)
FILE=ture
echo "FILE is $FILE"
;;
v)
VERBOSE=ture
echo "VERBOSE is $VERBOSE"
;;
c)
c=$OPTARG
echo "c is $c"
;;
\?)
echo "`basename $0` -[a h f v] -[c value] file"
;;
esac
done
-----------------