使用CRT软件登陆到linux虚拟机,使用pwd命令查看当前路径为/root目录php
使用vi编辑器编写第一个shell文件 hello.sh, 注意必定要以.sh结尾html
编写第一个shell文件,#!/bin/bash 是必需要写的,表示要是/bin/bash这个执行脚本的命令执行接下来写的脚本, echo "hello world !!"表示想前端打印一句话前端
经过chmod命令赋予该脚本的执行权限chmod 755 hello.sh,不然没有执行权限,/root/hello.sh表示在全路径下执行该shell脚本linux
./hello.sh 表示在当前路径下执行该shell脚本ios
bash hello.sh这种方式执行脚本,hello.sh中就不须要指定#!/bin/bash这句话,由于你已经指定了bash这种执行脚本方式的命令,固然加了#!/bin/bash也不会有问题git
像ls这种命令也能够算是一种脚本,可是咱们不须要添加路径就能执行,是由于该命令添加进系统环境变量(环境变量详解个人另外一篇经验)正则表达式
单引 双引 反引用[] [[]]sql
将命令的输出读入一个变量中,能够将它放入双引号中,便可保留空格和换行符(\n)shell
out=$(cat text.txt)编程
输出1 2 3
out="$(cat text.txt)"
输出:
1
2
3
--------------[]通常用于算术比较
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
逻辑与-a
[ $var1 -eq 0 -a $var2 -gt 2 ]
逻辑或
[ $var1 -eq 0 -o $var2 -gt 2 ]
[ condition ] && action 等价于if...fi
if [ "$LOOK_OUT" -gt "85" ]
if [ -e /home/slynux ]; then
...
fi
-----------------[[]]通常用于字符串比较
if [[ -n $str1 ]] && [[ -z $str2 ]] ;
then
commands;
fi
========================
一、字符串判断
str1 = str2 当两个串有相同内容、长度时为真
str1 != str2 当串str1和str2不等时为真
-n str1 当串的长度大于0时为真(串非空) if [[ -n $1 ]]
-z str1 当串的长度为0时为真(空串)
str1 当串str1为非空时为真
二、数字的判断
int1 -eq int2 两数相等为真
int1 -ne int2 两数不等为真
int1 -gt int2 int1大于int2为真
int1 -ge int2 int1大于等于int2为真
int1 -lt int2 int1小于int2为真
int1 -le int2 int1小于等于int2为真
3 目录文件的判断(if [ ])
-r file 用户可读为真
-w file 用户可写为真
-x file 用户可执行为真
-f file 文件为正规文件为真
-d file 文件为目录为真
-c file 文件为字符特殊文件为真
-b file 文件为块特殊文件为真
-s file 文件大小非0时为真
-t file 当文件描述符(默认为1)指定的设备为终端时为真
三、复杂逻辑判断
-a 与
-o 或
! 非
下面是一些使用实例:
#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"
#这里的-x 参数判断$myPath是否存在而且是否具备可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
#这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
#这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
#其余参数还有-n,-n是判断一个变量是不是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
#两个变量判断是否相等
if [ "$var1" == "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
-----------------获取名称.扩展名
file_jpg="sample.jpg"
name=${file_jpg%.*}
输出sample
file_jpg="sample.jpg"
extension=${file_jpg#*.}
输出jpg
------------------ time 计算命令执行时间
time command
--------------- 重定向
0 stdin标准输入
1 stdout标准输出
2 stderr标准错误
文件打开模式:
> 等同于1> 截断模式
>>等同于1>> 追加模式
<用于从文件中读取至stdin 只读模式
ls + 2> out.txt
stdout不会有任何输出,由于错误已经重定向到out.txt中了
能够将stderr单独重定向到一个文件,将stdout重定向到另外一个文件:
cmd 2>stderr.txt 1>stdout.txt
将stderr转换成stdout,使得stderr和stdout都被重定向到同一个文件:
cmd 2>&1 output.txt
或者
cmd &> output.txt
将stderr输出丢弃
some_command 2> /dev/null
将文件重定向到命令
cmd < file
向log文件中写入头部数据
#!/bin/bash
cat <<EOF>log..tt
LOG FILE HEADER
this is a test log file
EOF
-----------------------/dev/null 2>&1
*/1 * * * * root /usr/local/php/bin/php /var/w.php > /dev/null 2>&1
crontab内容:50 18 5-30 * * /script/myscript.sh 1> /dev/null 2>&1
其中 1> /dev/null 2>&1是什么意思??
dev/null 为系统垃圾箱
&为后台运行
可是 myscript 后面的1 和 /null后面的2 还有 &后面的1是什么意思?
1表明标准输出,2表明错误信息输出.
1>/dev/null 就是指将标准输出定向到空设备,
2>&1,的意思是将错误输出定向到和1同样的输出设备,也一样是空.
换句话说,就是不显示该程序执行过程当中的任何信息
cmd >a 2>a 和 cmd >a 2>&1 为何不一样?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍 ,由此致使stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道以后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开
他们的不一样点在于:
cmd >a 2>a 至关于使用了FD一、FD2两个互相竞争使用文件 a 的管道;
而cmd >a 2>&1 只使用了一个管道FD1, 但已经包括了stdout和stderr。
从IO效率上来说,cmd >a 2>&1的效率更高。
----------------- 算数运算 let expr
let 能够直接执行基本的算数操做
no1=4
no2=5
let result=no1+no2
echo $result
let no1++
let no1+=6
操做符[] ,expr 和let命令相似
result=$[ no1 + no2 ]
result=$[ $no1 + $no2 ]
result=`expr 3 + 4`
result=$(expr $no1 + 5)
---------------- 浮点运算 bc
#echo "4 * 0.56" | bc
2.24
-----------------得到字符串长度
var=123456
echo ${#var}
-----------------环境变量$PATH和export
echo $PATH
PATH一般定义在/etc/environment或/etc/profile或~/.bashrc中
export命令用来设置环境变量;
添加新的路径:
export PATH="$PATH:/home/user/bin"
或者
PATH="$PATH:/home/user/bin"
export PATH
其它环境变量:HOME,PWD,USER,UID,SHELL
查看进程相关的环境变量:
cat /proc/$PID/environ
----------------- printf 格式化输出
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 James 91.32
输出为:
No Name Mark
1 James 91.32
%-5s 指明了一个格式为左对齐且宽度为5的字符串替代(- 表示左对齐)
-4.2f 表示对浮点数的处理格式
-------------- 读取命令返回值$?
cmd;
echo $?;
-------------------------shell 调试
#!/bin/bash -xv 不用任何其余选项就能够启用调试功能了
sh -n sh16.sh 不执行script,仅查询语法
sh -x sh16.sh 将script执行过程所有列出来
须要给变量赋值时,能够这么写:
变量名=值
要取用一个变量的值,只需在变量名前面加一个$
a="hello world"
echo "A is:" $a
//if 注意空格
a=$1
if [[ $a -eq 2 ]] ;then
echo "1"
else
echo "2"
fi
if [[ $a = gjslint ]] ;then
echo "1"
exit 0
else
echo "2"
fi
exit 0
===================== 调用php的sh
#!/bin/bash
if [[ $0 = /* ]]
then
curfile="$0"
else
curfile="$PWD/${0#./}"
fi
#获得curfile 为/usr/local/shell/automation/autoupdate_host.sh
php_path=`dirname $curfile`
#获得php_path为/usr/local/shell/automation
PHP="/usr/local/php/bin/php -q "
PROGRAM="${php_path}/clear_his.php"
#echo $PHP $PROGRAM &
$PHP $PROGRAM &
====================== [和[[有什么不一样
$ type [
[ is a shell builtin
$ type [[
[[ is a shell keyword
也就是说[处理里面的字串是看成参数来处理的,而[[对待其中的字串是看成表达式来处理的
那么看成参数和表达式有什么不一样呢?
表达式中不会有wordsplitting 或者glob expansion,而参数处理会有
$ ls
file file 1 #注意是2个文件(file 和file 1)
$ (foo="file 1";[[ -f $foo ]]&&echo "$foo is a file")
file 1 is a file
]$ (foo="file 1";[ -f $foo ]&&echo "$foo is a file") # 这里file 1被分红2个word,因此出错
bash: [: file: binary operator expected
再来看看glob expansion
$ touch '*'
$ (foo="*";[ -f $foo ]&&echo "$foo is a file") #为何显示too many arguments,由于 *被扩展为全部目录下的文件
bash: [: too many arguments
$ (foo="*";[[ -f $foo ]]&&echo "$foo is a file") # *被当成普通字符了
* is a file
参数传递中<和>会被解析成重定向符号,因此必须转义掉
$ ([ "s" < "l" ]&&echo yes) #错误使用
bash: l: No such file or directory
$ ([ "s" \> "l" ] &&echo yes) #正确使用
yes
$ ([[ "s" > "l" ]] &&echo yes) #而在表达式中比较符号不会被看成重定向符号
yes
参数传递中小括号会被分割成token,而在表达式中则会被解析成运算顺序
$ ([ "s" \> "l" -a ( file "l" \> "a" -o "l" \> "p" ) ]&&echo yes) #(和)必须被转义,以免参数解析中的不正确分词
bash: syntax error near unexpected token `('
$ ([ "s" \> "l" -a "l""a"−o"l""p" ] &&echo yes)
yes
$ ([[ "s" > "l" && ( "l" > "a" || "l" > "p" ) ]] &&echo yes; ) #而表达式则不须要考虑这个
yes
================ shell判断文件是否存在
shell判断文件,目录是否存在或者具备权限
#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"
# 这里的-x 参数判断$myPath是否存在而且是否具备可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
# 这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
# 这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
# 其余参数还有-n,-n是判断一个变量是不是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
# 两个变量判断是否相等
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
-f 和-e的区别
Conditional Logic on Files
-a file exists.
-b file exists and is a block special file.
-c file exists and is a character special file.
-d file exists and is a directory.
-e file exists (just the same as -a).
-f file exists and is a regular file.
-g file exists and has its setgid(2) bit set.
-G file exists and has the same group ID as this process.
-k file exists and has its sticky bit set.
-L file exists and is a symbolic link.
-n string length is not zero.
-o Named option is set on.
-O file exists and is owned by the user ID of this process.
-p file exists and is a first in, first out (FIFO) special file or named pipe.
-r file exists and is readable by the current process.
-s file exists and has a size greater than zero.
-S file exists and is a socket.
-t file descriptor number fildes is open and associated with aterminal device.
-u file exists and has its setuid(2) bit set.
-w file exists and is writable by the current process.
-x file exists and is executable by the current process.
-z string length is zero.
==================bash中的特殊符号
* 万用字符,表明一个或多个字符(或数字)
? 万用字符,表明一个字母
# 批注,这个最常被使用在 script 当中,视为说明!
\ 跳脱符号,将『特殊字符或万用字符』还原成通常字符
| 分隔两个管线命令的界定;
; 连续性命令的界定(注意!与管线命令并不相同)
~ 使用者的家目录
$ 亦便是变量以前须要加的变量取代值
& 将指令变成背景下工做
! 逻辑运算意义上的『非』 not 的意思!
/ 路径分隔的符号
>, >> 输出导向,分别是『取代』与『累加』
' 单引号,不具备变量置换的功能
" 具备变量置换的功能!
` ` 两个『 ` 』中间为能够先执行的指令!
( ) 在中间为子 shell 的起始与结束
[ ] 在中间为字符的组合
{ } 在中间为命令区块的组合!
exit 1:退出整个程序
--------------------dirname
dirname /home/bin/abc
获得/home/bin
------------------------- 循环读取每行 :
all_corp=sql.txt
cat $all_corp | while read line
do
echo $line
done
-----------------------整数比较
-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]
if [ $counter -gt 1 ]; then
...
fi
< 小于(须要双括号),如:(("$a" < "$b"))
<= 小于等于(须要双括号),如:(("$a" <= "$b"))
> 大于(须要双括号),如:(("$a" > "$b"))
>= 大于等于(须要双括号),如:(("$a" >= "$b"))
---------------------------字符串比较
= 等于,如:if [ "$a" = "$b" ]
== 等于,如:if [ "$a" == "$b" ],与=等价
注意:==的功能在[[]]和[]中的行为是不一样的,以下:
1 [[ $a == z* ]] # 若是$a以"z"开头(模式匹配 )那么将为true
2 [ $a == "z*" ] # 若是$a等于z*(字符匹配 ),那么结果为true
3
4 [ $a == z* ] # File globbing 和word splitting将会发生
5 [ "$a" == "z*" ] # 若是$a等于z*(字符匹配),那么结果为true
一点解释,关于File globbing是一种关于文件的速记法,好比"*.c"就是,再如~也是.
可是file globbing并非严格的正则表达式,虽然绝大多数状况下结构比较像.
!= 不等于,如:if [ "$a" != "$b" ]
这个操做符将在[[]]结构中使用模式匹配.
< 小于,在ASCII字母顺序下.如:
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
注意:在[]结构中"<"须要被转义.
> 大于,在ASCII字母顺序下.如:
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
注意:在[]结构中">"须要被转义.
具体参考Example 26-11来查看这个操做符应用的例子.
-z 字符串为"null".就是长度为0.
-n 字符串不为"null"
注意:
使用-n在[]结构中测试必需要用""把变量引发来.使用一个未被""的字符串来使用! -z
或者就是未用""引用的字符串自己,放到[]结构中。虽然通常状况下可
以工做,但这是不安全的.习惯于使用""来测试字符串是一种好习惯.
awk \'{print $2}\' class.txt | grep \'^[0-9.]\' > res
iptables 配置文件目录 /etc/sysconfig/iptables
1.别名 alias,存放位置 $HOME/.bashrc
alias ll=\'ls -lh\'
2.print=helloworld echo ${print}
3.变量:内存中一块存储单元
本地变量:登录登出生命周期内有效,只限制于本用户
变量名=变量值
set 查看
LOCAL="TEST"
echo $LOCAL
设置变量名为只读,不能在更改,同是也不能在恢复:readonly 变量名,不能删除。
环境变量:系统变量,用于全部用户,只有环境变量才能用于全部的子进程中,本地变量不能够。
存放于/etc/profile .bash_profile
export 变量名=变量值
env或者export查看
unset 变量名 删除
变量替换:用变量的值替换变量的名
print=helloworld
echo ${print}
echo ${file1}+${file2}
--------------------位置变量:$0 $1...$9
$0:脚本的名字
$1:脚本的第一变量
$2:脚本的第二变量
向脚本中使用位置参数:./test.sh a b c
向系统命令传递参数
find /root/ -name $1 -print
./test.sh aa
标准变量:bash默认的,能够在/etc/profile中定义
EXINIT
HOME
IFS:设置分隔符,默认为空格 IFS=":"SHE
LOGNAME
MAIL 默认邮箱位置
MAILPATH多个邮箱时能够设置
TERM 显示终端类型
PS1 当前shell目录格式PS1="WANGJIAN:"
ps2 >
pwd显示当前路径 SHELL 显示当前shell
MANPATH TERMINFO
----------------------------------------------------------特殊变量
$# 变量的个数 $* 显示脚本所有参数(参数列表)
$$脚本运行的当前id号
$?显示前一个命令的运行状态
$!后台运行的最后一个进程id号
#!/bin/bash
echo "tesh.sh"
echo "this is first variable locate:$1"
echo "this is second variable locate:$2"
echo "this is third variable locate:$3"
shift
echo "count:$#"
echo "all list:$*"
echo "pid:$$"
echo "status:$?"
./tesh.sh a b c
declare :设置或显示变量 -f只显示函数名
export:建立环境变量 -p显示全部环境变量
readonly:设置只读变量,不能修改删除
unset:取消变量的定义。-f 删除只读变量
shift:输入的位置变量改变位置 shift 表位置上移一个位置,shift 2 表上移动两个位置
双引号"":引用字符或字符串除$ \ `
单引号\'\':直接引用为字符或字符串
反引号``: 做为系统命令执行 echo `echo wangjian` wangjian
反斜杆\:转义特殊字符($*?)为普通字符
运算符:~取反 << >>移位 &与(同1为1,否0) |或(有1为1,全0为0) ^异或 逻辑运算符号&& ||
运用运算符:$[]:表示对其中的表达式求值 echo $[2+8] echo $[3&4] $[]等价于(())
[base#n] n(base>n)表示基数从2到36的任何基数 echo [10#8+1] 结果为9
let a+=3 a=a+3
表达式优先级别[] *= || && | ^ & ==
shell 的输入与输出
echo
-e 解析转义字符 echo -e "this is a bag \n\n\n"
-n 回车不换行,默认换行 echo -n "this is a cat"
转义字符(\c回车不换行 \f禁止 \t跳格至关tab \n回车换行)
read:能够从键盘或文件的某一行文本中读入信息,并将其赋给一个变量。
read varible1 varible2
若是只指定了一个变量,那么read将会把全部的输入赋给改变量,直至遇到文件结束或回车。若是多个变量,就依次赋给。shell用空格做为变量之间的分隔符。
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo -e "your first name :${firstname}\n"
echo -e "your last name :${lastname}\n "
read -t 5 variable 5秒钟超时
read -p "Please enter your Username: " user -p prompt 提示语
[root@ceshiji ~]#Please enter your Username:
read -s -p "Please enter your Password: " pass -s charaters are not echoed. 字符不回显示。指输入以后,不在回显
cat:显示文件内容,建立文件,还能够用它来显示控制字符
cat file1 file2 file3 同时显示
cat file1 file2 file3>myfile
cat -v dos.txt (-v 显示控制符)
管道|:一个命令的输出传给一个命令的输入
df -k|awk \'{print $1}\'|grep -v \'Filesystem\'
tee:把输出的一个副本输送到标准输出,另外一个副本拷贝到相应的文件中。
tee files 在看见输出的同时,也将其存入一个文件。通常用于管道以后。
tee -a files 追加到files中 (-a 表追加)
who|tee who.out
标准输入 0
标准输出 1
标准错误 2
重定向:改变程序运行的输入来源和输出来源。
> >> < <<
command>>filename 2>&1
command <filename>filename2
cat file|sort 1 > sort.out 等价于cat file|sort > sort.out
pwd >> file.txt
>nullfile建立一个字节为零的文件 >文件名
sort < file
cat >> aa.txt << CHINAITLAB 把CHINAITLAB结尾的内容都追加到aa.txt
>HELEO ,I AM WANGJIAN
>MY NAME IS $HOME
>bye ...
>CHINAITLAB
重定向标准错误:grep \'test\' file.txt 2>error.txt
grep "test" test.txt>error.txt 2>&1 有没有错误都输入到error.txt
exec用来替代当前的shell,并无启动子shell,而是清楚现有shell环境,从新启动一个shell
exec command
exec ./test.sh exec一般后接一个shell脚本
文件描述符
3-9可使用 0输入 1输出 2错误
exec 3 <&0 0<name.txt 此时不会关闭当前的shell
控制流结构: if then eles case for until while break continue
if then
elif then
elif then
else
fi
if 条件1
then
语句
elif 条件2 (条件1不成立,执行条件2)
then
else (条件1 2都不成立,执行else)
语句
fi (结束)
if语句必须以单词fi终止
if $x=sedsrc;then
echo
then
echo
fi
if [ "10" -lt "12" ]
man test
echo -n "enter your name:"
read NAME
if [ "$NAME" == ""];
then
echo "you did not enter any information"
else
echo "your name is $NAME"
fi
if cp myfile.bak myfile;
then
echo "GOOD COPY"
else
echo "basename $0 :error could not copy the files" >&2
case:多选择语句。若是匹配成功,执行匹配的命令
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
*表任意字符,?表任意单字符 []表范围
echo -n "enter a number from 1 to 3;"
read ANS
case $ANS in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "basename $0 :this is not between 1 and 3" >&2
;;
esac
case $1 in
get|GET)
create_dir
get_config_file
;;
put|PUT)
put_config_file
;;
stop|STOP)
stop_server
;;
start|START)
start_server
;;
restart|RESTART)
restart_server
;;
*)
echo
echo "$Color_err Useage: ./Configure_squid.sh get|put|stop|start|restart $Color_end"
echo
exit 1
;;
esac
for
for 变量 in 列表
do
命令1
命令2
done
for语句 :提供循环执行
使用格式:
for var in values #var是变量 values是一组值
do
语句 #能够是多条语句
done
注意values的值能够所有列出,也但是通配的方式,也能够是某命令的输出值(如$(ls))。
values的值能够是:
1.列表 in 1 2 3 4 5 用空格隔开
2.文件 in file1 file2 file3
3.变量 in $a 命令输出赋值
4.命令 in `ls abc*`
5.字符串表 in "orange red blue gray"
5.特殊: 有时没有in 此时将命令行参数传入
for loop
do
find / -name $loop -print
done
[root@localhost ~]# ./sh match
/root/match
[root@localhost ~]# cat sh
#!/bin/bash
for loop
do
find /root -name $loop -print
done
#!/bin/sh
for ((i = 1; i < 254; i++)) #必须用两个括号
do
arping -I eth0 60.191.82.$i -c 1
done
arp -a > mac_table
当变量值在列表里,for循环即执行一次全部命令,使用变量名访问列表中的取值。命令可为任何有效的shell命令和语句。变量名为任意单词。in列表用法是可选的,若是不用它,for循环使用命令行的位置参数。in列表能够包含替换、字符串和文件名。
for((i=1;i<=10;i=i+1))
do
touch ar_$i;
touch full_$i;
done;
for i in {1..100}
do
.......
done
#!/bin/sh
for i in `seq 1 100`
do
echo $i
done
for loop in 1 2 3 4
do
echo $loop
done
for loop in "orange red blue grey"
do
echo $loop
done
for i in $(ls); do du -sh $i; done | sort -n 查看当前目录的大小按小--大排列
until 条件
do
命令1
命令2
...
done
条件可为任意测试条件,测试发生在循环末尾,所以循环至少执行一次.
read look
until [ "$look" ]
do
echo "full"
done
sleep 1
nohup ./test.sh &
while 命令
do
命令1
命令2
...
done
$ cat "filelist.txt"
name.txt□
txtf
□a□b□c□
$ while read file; do echo "$file"; done < "filelist.txt"
name.txt
txtf
a□b□c
echo "press ctrl+d ,stop"
while echo -n "enter a file for you like:" ; read film
do
echo " Yeah ,${file} is a good film "
done
while read line
do
echo $line
done<name.txt
break [n]:跳出循环,若是是在一个嵌入循环里,能够指定n来跳出的循环个数
continue:跳过循环步骤(本次循环)
continue只能跳过本次循环。
while :<无限循环,须要加入break跳出>
while:
do
echo -n "enter any number [1...5]"
read ANS
case $ANS in
1|2|3|4|5)
echo "you enter a number between 1 and 5"
;;
*)
echo "wrong number ,bye."
break
;;
esac
done
shift n :参数向左偏移n位。
exit :退出系统
wc -l 查看文件的行数
getopts 多参数传递
ls -R 文件夹 递归查看
iostat 1
umount -a
sync:将缓冲区的内容写到磁盘
r !date :读入日期
r 文件 从文件中读入
!pwd 执行命令 查看当前目录
r !pwd 插入当前目录
文本过滤
正则表达式:由一些字符要(元字符)组成,匹配字符串,过滤所需。
元字符:
^ :只匹配行首 $:只匹配行尾 *:匹配0个或多个此单字符
[]:只匹配[]内字符,能够是一个单字符,也能够是字符列表。可使用-表示[]内字符序列范围,入用[1-5]代替[12345]
\:只用来屏蔽一个元字符的特殊含义 . 只匹配任意单字符,如...x..x..x
pattern\{n\}:只用来匹配前面pattern出现次数,n为次数
pattern\{n,\}:含义同上,但次数最少为n
pattern\{n,m\}:含义同上,但pattern出现次数在n与m之间.
A\{2\}B:A出现两次 AAB
A\{4,\}B:A最少出现4次,AAAAB AAAAAB
A\{2,4\}B: A出现次数范围2-4次
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}匹配ip地址
^:只容许在一行的开始匹配字符或单词.
^d
drwxrwxrw- 匹配 -rwx--x--x 不匹配
^...1
3351xc 匹配 338xcd 不匹配
$:与^相反,只容许在行尾匹配字符或字符串
trouble$
^$ :匹配空行 ^.$:匹配包含一个字符的行
*:匹配任意字符包括零个字符 如300*2 3002 匹配
\:屏蔽一个特殊字符 如* $ .
\*\.pas:匹配以*.pas结尾的全部字符或文件.
[]:匹配一个范围或集合 ,用逗号分开. 用-表示范围
[0-9] [a-z] [A-Z a-z 0-9] [S,s]
find:用来查找具备某些特征的文件的命令.遍历大的文件系统时,通常放在后台运行.
find path -options [-print -exec -ok]
-print 输出到标准输出
-exec 对匹配的文件执行该参数所给出的shell命令 形式为 command {} \; 注意{}和\;之间有空格
find . -type f -exec ls -l {} \;
find . -name "*.log" -mtime +5 rm {} \;
有时参数太长或参数列溢出,此时要用xargs 相似与exec
find / -perm -7 -print |xargs chmod o-w
find / -type f -print |xargs file
-ok 和-exec做用相同,只不过-ok以一种更安全的方式运行.
-options:
-name文件名 文件名要引号
find ./ -name "aa.txt" -print
find ./ -name "[A-Z]*" -print 大写开头的
-perm文件权限
find -perm 755 -print (路径没有表示为当前目录)
-user文件的属主
find `pwd` -user root -print
-group 文件的属组
find ./ -group root -print
-atime ctime mtime -n +n -n 表示文件更改距如今n天之内(以内),+n表示文件更改时间距如今n天之前
find 、-mtime -5 -print 修改在5天内的文件
-size n[c] 查找文件长度为n块的文件,带有c表示文件长度以字节计算
find . -size +1000000c -print 大于1000000c字节的文件
find . -size -100 小于100块的文件
-type 类型 b p c f(普通文件)
-nouser -nogroup 无属主,属组的文件 ,删除用户时产生
find / -nouser -print
find / -newer "myfile" !-newer "yourfile" -print 查找比文件myfile新比yourfile旧的文件
-depth 在子目录中查找
find . -name "aa.txt" -depth -print
grep 对文本文件进行模式查找
grep "jeny" *.txt
grep -c (只输出匹配的行数)
grep -c "aa" aa.txt
grep -n (显示匹配的行和行号)
grep -i (忽略大小写)
grep -v (反向查找)
grep -h (查询多文件时不显示文件名)
grep -H (显示文件名)
grep -s (不显示不存在或无匹配文本的错误信息)
grep "2004:22:5[0-9]" aa.txt
grep "^[^210]" myfile 不显示是210的行:包括二、一、0 打头的行
grep "\?" aa.tet 查找?
grep "[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}" qshengyang12.xml 过滤除ip地址
grep "[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}" qshengzheng12.xml过滤mac地址
grep的命令类别
[[:upper:]] 等价于[A-Z]
[[:alnum:]] 等价于[0-9 a-z A-Z]
[[:lower:]] 等价于[a-z]
[[:space:]] 等价于空格或tab键
[[:digit:]] 等价于[0-9]
[[:alpha:]] 等价于[A-Z]
service dhcpd start > /dev/null 不显示
grep "5[[:digit:]][[:digit:]]" file 在file中查找500 到599
nmap -sT ip地址
arping ip 地址
awk:是一种自解释的编程语言,可从文件或字符串中基于指定规则浏览和抽取信息。
awk脚本由各类操做和模式组成
模式和动做
模式部分决定动做语句什么时候触发及触发事件。(BEGIN,END)
动做对数据进行处理,放在大括号{} 内指明。(print)
分隔符号、域和记录
awk执行时,其浏览域标记为$1,$2....$n。这种方法称为域标识。$0为全部域。
注意执行时不要混淆符号$和shell提示符$,它们是不一样的。
三种方式调用awk
命令方式:awk [-F filed-spearator] \'command\' input-files 用单引号 -F 来指定分隔符如 -F :
awk脚本:脚本文件
awk命令插入一个单独文件: awk -f awk-script-file input-files
awk中的$跟shell中不含义不一样 $0 是全部域,$1是第一个域 ,$2是第二个域....
awk \'{print $0}\' score.txt 按行打印文件score.txt的各行.即打印全部域。
awk -F : \'{print $0}\' score.txt默认分隔符是空格,能够用-F 来指定 本例子是:
awk \'{print $1 "\t" $3}\' score.txt 打印显示第1和第3个域
awk \'BEGIN {print "num ip/n-----"} {print $1 "\t" $4} END {print "end-of-report"}\' ab.txt BEGIN和END定义了报头 num ip 打印显示第1和第4个域,最后显示end-of-report
num ip
-----
64 172.0.0.1
函数定义:shell容许将一组命名集或语句造成一个可用块,这些块称为shell函数
格式:
函数名()
{
命令1
...
}
function 函数名()
{
....
}
定义函数
#!/bin/bash
function hello ()
{
echo "hello ,today is `date`"
return 1
}
echo "this is a function test"
hello
调用:直接输入函数名
hello
参数传递到函数中
向函数传递参数就像在脚本中使用位置变量$1,$2,$3....$9
#!/bin/bash
function hello ()
{
echo "hello ,$1 today is `date`"
return 1
}
echo "this is a function test"
hello wangjian
显示: hello ,wangjian says: today is Fri Oct 12 18:05:25 csT 2007
函数文件
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
>文件名:建立大小为0的空文件
查看载入函数:set
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
set
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
删除函数:unset
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
unset
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
函数返回值:返回return的值 return 是何值就是何值。
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
unset
echo "now going to the function hello"
hello
echo $?
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
awk深刻学习
awk中特殊元字符 :+:表任意字符 ?:表单个字符
匹配操做符:~:匹配 !~:表示不匹配 使用:~/匹配内容/
cat score.txt|awk \'$0~/218.79.131.96/\'
awk \'$0 !~/218.79.131.96/\' score.txt
awk \'{if ($1=="218.79.131.96") print $0}\' score.txt
man awk
sed介绍
sed 选项 命令(\'\') 文件
sed不与初始化文件打交道,它操做的只是一个拷贝,而后全部的改动若是没有重定向到一个为文件,将输出到屏幕。
sed是一种重要的文本过滤工具,使用一行命令或者使用管道与grep与awk相结合
非交互性文本流编辑。
调用sed有三种方式
使用sed命令行格式为:sed [选项] sed命令 输入文件命令用\'\'刮起来
使用sed 脚本文件,格式:sed [选项] -f sed 脚本文件 输入文件
sed脚本文件 [选项] 输入文件
无论是使用shell命令行方式或脚本文件方式,若是没有指定输入文件,sed从标准输入中接受输入,通常是键盘或重定向结果。
sed命令选项
n 不打印没匹配的
c 下一命令是编辑命令
f 正在调用sed脚本文件
sed 在文件中查询文本的方式
使用行号,能够是一个简单数字,或者是一个行号范围。
使用正则表达式
x 为一行号
x,y 表示行号范围从x到y
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
pattern/,x 在给定的行号上查询包含模式的行
x,/pattern/ 经过行号和模式查询匹配行 (从x行匹配到/pattern结束)
x,y!查询不包含指定行号x和y的行
基本sed编辑命令
p:打印匹配行
=:显示文件行号
a\:在定位行号后附加新文本信息后面(分两行写)
i\:在定位行号后插入新文本信息前(分两行写)
d:删除定位行
c\:用新文本替换定位文本
s:使用替换模式替换相应模式
r:从另外一个文件中读文件
w:写文本到一个文件
q:第一个模式匹配完成后推出或当即推出
l:显示与八进制ascii代码等价的控制字符
{} 在定位行执行的命令组
n 从另外一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到/pattern n/
y 传送字符
例子:
sed \'2p\' aa.txt 打印第2行(其余也打印)
sed -n \'2p\' aa.txt 只打印第二行
sed -n \'1,4p\' aa.txt 只显示1-4行
sed -n \'/los/p\' aa.txt 只显示 含有los的行
sed -n \'4,/los/p\' aa.txt 只显示从第四行开始知道匹配到los为止的之间全部行
sed -n \'/^$/=\' aa.txt 只显示空行
sed -n -e \'/^$/p\' -e \'/^$/=\' aa.txt 只显示空行和空行行号(-e 表示多命令同时执行)
sed -n \'/beijing/a\/shenzhen/\' aa.txt 在beijing所在行的下一行追加shenzhen(命令从/shenzhen/\' aa.txt换行(不改变aa)输入)
sed -n \'/beijing/i\/shenzhen/\' aa.txt 在beijing所在行的前一行插入shenzhen(命令从/shenzhen/\' aa.txt换行输入)不改变aa ,但能够重定到一个文件中改变原文件)
sed -n \'/beijing/c\/shenzhen/\' aa.txt 将beijing所在行替换shenzhen(命令从/shenzhen/\' aa.txt换行输入)(不改变aa ,但能够重定到一个文件中改变原文件)
sed \'1,2d\' aa.txt 删除1和2行
sed \'s/beijing/shanghai/g\' aa.txt
sed -n \'s/china/&hello/p\' aa.txt 在匹配到china字符后追加hello
sed -n \'s/china/hello &/p\' aa.txt在匹配到china字符前追加hello
sed \'1r bb.txt\' aa.txt 在aa.txt的第一行下面插入bb.txtwenjian
sed \'/china/q\' aa.txt 匹配到第一个china就退出
sed -n \'/china/l\' aa.txt 以八进制显示
info sed man sed
sed \'/m/G\' 文件名搜索到回车加一个空行
awk \'/from/{print}\' 名打印全部含有from的行
-------------------------合并与分隔
sort 选项 files
许多不一样的域按不一样的列顺序分类
-c 测试文件是否已经分类
-m合并两个分类文件
-u删除全部复制行
-o 存储sort 结果的输出文件名
-t 域分隔符;用非空格或tab键分隔域
+n n为域号,使用此域号开始分类
n指定分类是域上的数字类项
-r 比较求逆
man sort
sort -c aa.txt
sort -u aa.txt 合并,有重复的行只显示第一个
sort -r aa.txt 求逆,从下向上排序
sort -t "." +2 aa.txt 分隔符为. 对第2个域进行ASCII码排序 域号从0 1 2 ..
sort -t "." +2n aa.txt 分隔符为. 对第2个域进行数字排序域号从0 1 2 ..
-----------------------uniq 选项 file
从一个文本文件中去除或禁止重复的行
-u 只先显示不重复的行
-d 只显示有重复的数据行,每种重复行只显示一行
-c 打印每一重复行出现次数
-fn n为数字,前n个域被忽略,只比较后面
man uniq
uniq -c file 查看重复次数(这里重复指的是相邻重复,隔行重复不算)
uniq -d file 只显示有重复的数据行,每种重复行只显示一行(相邻重复,隔行重复不算)
uniq -f 2 myfile.txt 前2个域被忽略,从后面的域比较
uniq -d
sort aa.txt|uniq -c 等价于 sort -u aa.txt 查看重复次数(这里重复指的是相邻重复和隔行重复)
深刻讨论awk
条件操做符
~:匹配正则表达式
!~:不匹配正则表达式
&&:and
||:or
!:not
awk \'{if ($1~/^4/) print $0}\' file 若是文件file中第一个域匹配是4开头的行就所有显示
awk \'{if ($1!~/^4/) print $0}\' file 若是文件file中第一个域匹配不是4开头的行就所有显示
awk \'{if ($4~/^\[07\/jul\/2004/) print $0}\' file 打印是[07/jul/2004]开头的全部行
--------------------------awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk 浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令-F选项。
NF 浏览文件域的个数
NR 已度的记录数(行数)
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
文件aa的内容为
ab#slfjslk
cd#fslkjf
df#123fjls
eb#j9sq
op#9sjtr
awk -F \'#\' \'{print NR,NF,$0}\' aa 打印行数 域数 全部记录
awk -F \'#\' \'{print ENVIRON["USER"],FILENAME, $0 ARG ARGV[0]}\' aa 打印USER环境变量,文件名,全部记录,参数个数,第一个参数。
--------------------------------字符串函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t)在整个t(域或记录)中s替换r
index(s,t)返回s中字符串t的第一位置
length(s)返回s的长度
match(s,r)测试s中是否包含匹配r字符串
split(s,a,fs)用fs域上将s分红序列a
sprint(fmt,exp)返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子串代替s
substr(s,p) 返回字符串s中从p开始的后部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后部分
awk -F \'#\' \'{if(gsub("s","S",$1)) print $1}\' aa.txt 替换文件aa.txt的$1中s变成S
awk -F \'#\' \'{if(gsub("s","S")) print $0}\' aa.txt 默认是$0
awk -F \'#\' \'{print(index($2,"s")) }\' aa.txt 打印$2中s字符所在的位置。(注意是字串在前)
awk 转义字符
\b 退格键
\t tab键
\f 走纸换页
\ddd 八进制值
\n 新行
\c 任意其余特殊字符,例如\\为反斜线符号
\r 回车符
awk -F \'#\' \'{print(index($2,"s"),"\t" ,$2) }\' aa.txt
-------------------------------- printf修饰符%c ASCII字符%d 整数%f 浮点数,例如(123.44)%e 浮点数,科学记数法%f 新行%g awk 决定使用哪一种浮点数转换e或者f%o 八进制数%s 字符串%x 十六进制数awk 数组awk \'BEGIN {print split ("as*123",array2,"*")}\'./awk_arry.sh grade.txt############### main menu()###############curdate=`date "+%Y-%m-%d %T"`date "+%Y-%m-%d %T"显示当前日期和时间case $a in7)exit;;*)clearcontinue;;esac