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

shell脚本--常用知识

2013-12-01 11:02 288 查看
hello world!

#! /bin/bash

echo “hello world!”

$ chmod +x a.sh

$ ./a.sh

hello world!

变量

变量不分类型 (没有int,char,string)

不需要声明,直接使用

赋值:name=value (左右两边不能有空格)

使用:$name ${name}


foo=h

echo ${foo}ello

变量的作用域

默认全局作用域(仅当前shell可见)

local 限定函数局部变量

function a() { local msg; }

使用export导出变量,让子shell可以继承

export var=1

source 或 .(dot) 在当前shell下执行脚本

source ./config.sh

变量分类

自定义变量

环境变量 (set命名可查看)

$PATH,$IFS,$PS1,$PWD,$LINENO

位置参数(Positional Parameters)

$1 $2 $3 … ${10}

特殊参数(Special Parameters)

$#:位置参数的数量

$*:所有位置参数的内容 ($1 $2 …)

$@: 所有位置参数的内容(“$1” “$2” … )

$?:命令执行后返回的状态

$$:当前进程的进程号

$!:后台运行的最后一个进程号

$0:当前执行的进程名

玩转变量

使用eval实现变量的间接引用

x='abc def'

y='$x'

echo $y

$x

eval echo $y

abc de

玩转变量(续)

${!p} #双重引用

a=1

b='a'

echo ${!b}

1

${!p*} #返回所有以p开头的变量

echo ${!P*}

PATH PIPESTATUS PPID PS1 PS2 PS4 PWD

${p:-word} #如果变量p不存在,返回"word”

${p:=word} #如果变量p不存在,返回"word",并将p的值设为"word"

${p:?word} #如果变量p不存在,将"word"打入STDERR

${p:+word} #如果变量p存在,返回"word"

玩转变量(续)

if [${ret:=1} -ne 0 ]

then

echo “NO”

exit

fi

引号迷雾

双引号


使用双引号可解释$符号,反引号和反斜线等特殊字符

echo “$msg” => 显示msg变量值

单引号

与双引号类似,不同的是shell会忽略任何特殊符号

echo ‘$msg’ => 显示$msg

反斜杆

\c == ‘c’

反引号(命令替换)

用于执行系统命令并输出到变量

echo The date and time is `date`

几种括号

(list) list将在一个子shell中执行, 不会对当前shell产生影响,返回list的exit值

{ list; } 可以作组合命令用,list将在当前shell中被执行,list结尾处必须要有新行或‘;’号,返回list的exit值,list前后必须有空格

((expression)) 算术计算

[ ] [[ ]] 分支测试

数组

name=(value1 ... valuen) 此时下标从0开始

name[index]=value

unset name 或 name=

数组下标的范围没有任何限制,同时也不必使用连续的分量

$ A=(a b c def)

$ A[3]=bb

$ echo ${A[0]} #取第一个元素

a

$ echo ${A[@]} # 取全部元素

a b c def

$ echo ${#A[@]} # 取得数组元素的个数

4

数组(续)

遍历数组:

total=${#A[*]}

for ((i = 0; i < total; i++))

do

echo ${A[$i]}

done

分支语句

if list; then command;

[ elif list; then command; ] ...

[ else command; ]

fi

case $word in

[a-z]) list ;;

*) default;;

esac

[ $# -eq 1 ] && slen=1 || slen=0

条件测试

对文件、字符串和数字使用test命令。test一般有两种格式:

test condition 或 [ condition ](注意空格)

if [ $str = “a.txt” ];then

echo “OK"

fi

直接测试命令:

if grep abc a.txt &>/dev/null;then

echo “Bingo!”

fi

条件测试(续)

推荐使用[[ ]]进行条件测试

if [[ “x$str”== “xa.txt” && -f b.txt ]]

then

cmd;

fi

-f -d -z ……

man bash

CONDITIONAL EXPRESSIONS

条件测试 – 数值比较

if [ $a –lt 0 ]

then

echo OK

fi

推荐使用(( ))

if (( a > 0 ))

then

echo OK

fi

循环语句

for name [ in word ] ; do list ; done

for i in `ls *.result`;do cat $i; done

for (( expr1 ; expr2 ; expr3 )) ; do list ;done

for ((i=0;i<100;i++));do echo $i;done

while list; do list; done

while read line

do

echo $line

done < a.txt

until list; do list; done

注释

# 行注释 (#前要有空格)

echo $msg #print message

块注释

:<<COMMENT

echo $msg

COMMENT

comment()

{

echo $msg

}

正则表达式基础

元字符

. 匹配任何单个字符。

$ 匹配行结束符。^ 匹配一行的开始。

* 匹配0或多个正好在它之前的那个字符。

+ 匹配1或多个正好在它之前的那个字符。

? 匹配0或1个正好在它之前的那个字符。

\{i\} \{i,j\} 匹配指定数目的字符。

\ 这是引用符,转义;

[ ] [c1-c2] 匹配括号中的任何一个字符。 [^c1-c2]

\< \> 匹配词(word)的开始(\<)和结束(\>)。

\( \) 将 \( 和 \) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。

| 将 两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her)

正则表达式举例

HTML标签

<[^>]*>

匹配由26个英文字母组成的字符串

^[A-Za-z]+$

  

Email地址

\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

URL

[a-zA-z]+://[^\s]*

管道和重定向

管道可以把一条命令的输出作为另一条命令的输入

Command1 | Command2

返回值是最后一个命令的返回值

重定向

wc –l /etc/passwd > a.txt

wc –l /etc/passwd >> a.txt

wc –l < /etc/passwd

./command > a.txt 2>&1 (./command &> a.txt)

exec 5<> a.txt

echo “hello” >&5

<&-

>&-

作业控制

<CTRL-Z> 将当前任务挂起,返回job_id

fg job_id 把后台作业放到前台执行

bg job_id 把作业放到后台执行

vi b.sh

<CTRL-Z>

[1]+ Stopped vim b.sh

bg 1

[1]+ vim b.sh &

fg 1

vim b.sh

自定义函数

function foo() # foo为函数名

{

local a=$1; # 局部变量

echo $a;

return 0; # 返回值

}

foo “cool!” # 函数调用

echo $? # 打印返回值

自定义函数 – 16进制转点分十进制

a()

{

local str=$1

echo -n $((16#${str:0:2}))

str=${str:2}

if [ "x$str" = "x" ]

then

echo; return

else

echo -n "."; a $str

fi

}

#Usage

a "DDB14CCF"

整数计算

id++ id-- ++id –id - + ! ~ ** * / % 计算

<< >> & ^ | 位操作

<= >= < > == != 比较

&& || 逻辑操作

expr?expr:expr 三元操作符

= *= /= %= += -= <<= >>= &= ^= |= 赋值操作符

y=2000 闰年计算

echo $((y%4==0 && y%100!=0 || y%400==0))

(( y++ )) 自增1

tmp=$((16#a)) 进制转换

浮点运算

echo “scale=5; 3/7"|bc –l

.42857

echo "100.43KB 20.12KB" | awk '{print $1-$2}'

80.31

echo "ibase=16;F"|bc -l

15

简单字符串处理

x=abcd

${#x} # 获取字串长度

4

expr index $x “b“ # 获取子串所在偏移

2expr index $x "a“ # 获取子串所在偏移

1

echo ${x:1} # 获取子串

bcdecho ${x:2}cdecho ${x:0:2}

ab

简单的字符串处理(续)

x=aabbaarealwwvvwwecho “${x%w*w}“ # 截去尾部最短匹配

aabbaarealwwvvecho “${x%%w*w}“ # 截去尾部最长匹配

aabbaarealecho “${x##a*a}“ # 截去头部最长匹配

lwwvvwwecho “${x#a*a}“ # 截去头部最短匹配

bbaarealwwvvww

x=abcdabcdecho ${x/a/b} # 只替换一个bbcdabcdecho ${x//a/b} # 替换所有bbcdbbcd

简单字符串处理 – 实际应用

截去域名尾部

name=jx-sys-superdb.jx.baidu.com

echo ${name%%.*}

jx-sys-superdb

截取日期

str=20081011

year=${str:0:4}

替换

echo ${name//jx/tc}

tc-sys-superdb.tc.baidu.com

随机字符串生成

typeset -r DEFAULT_STR_LEN=5

typeset -ra dict=(a b c d e f g h i j k l m n o p q r s t u v w x y z)

function get_random_letter()

{

echo -n ${dict[$((RANDOM%${#dict[*]}))]}

return 0

}

function get_random_string()

{

local slen str

[ $# -eq 1 ] && slen=$1 || slen=$DEFAULT_STR_LEN

for ((i = 0; i < slen; i++))

do

str=${str}`get_random_letter`

done

echo $str

return 0

}

get_random_string $1

调试

-x

-n 是只语法检查而不执行任何命令

-e 是脚本发生第一个错误时就中止脚本运行,即当一个命令返回非零值时退出脚本 (除了until 或 while loops, if-tests, list constructs)

--posix 是更改Bash或脚本的行为,使之符合POSIX标准

Shell 伪信号:EXIT,ERR,DEBUG

调试(续)

+ typeset -r DEFAULT_STR_LEN=5

+ typeset -ra 'dict=(a b c d e f g h i j k l m n o p q r s t u v w x y z)'

+ get_random_string 2

+ local slen str

+ '[' 1 -eq 1 ']'

+ slen=2

+ (( i = 0 ))

+ (( i < slen ))

++ get_random_letter

++ echo -n t

++ return 0

+ str=t

+ (( i++ ))

+ (( i < slen ))

++ get_random_letter

++ echo -n k

++ return 0

+ str=tk

+ (( i++ ))

+ (( i < slen ))

+ echo tk

tk

+ return 0

信号捕获

#!/bin/bash

trap "print_OK" 3

function print_OK()

{

echo OK

}

while :

do

:

done

发送信号:kill -3 pid

屏蔽信号:trap “” 3

其他常用内置命令

exec command #用command替换当前进程

type ls

ls is aliased to `ls --color=tty`

: 空命令

while :

do

cmd

done

if [ list ]; then : ;else echo false;fi

常用工具

编辑软件: vi,emacs

联机帮助:man, info

查找类:find,locate,which,whereis,whatis

文本处理类:uniq,cut,paste,join,sort,comm,diff

二进制文件读取类:od,xxd,dd,hexdump

文本分析类:grep,sed,awk

系统状态类:top,ps,pstree,pgrep,/proc,strace,vmstat,netstat

传输类:wget

Grep - 全文匹配利器

--color 飘红匹配到的部分

-i 忽略大小写

-v 反向匹配

-r 递归匹配文件

-o 只打印匹配到的部分

-n 打印出行号

-c 统计匹配到的行数

-w 匹配整词

grep "sort“ *.doc

Awk – 文本处理利器

awk命令的一般形式: awk ' BEGIN { actions } pattern1 { actions } ............ patternN { actions } END { actions } ‘

awk -F: '{print $1} END{print "total:",NR}' /etc/passwd

Awk – 文本处理利器 (续)

取机器序列号

dmidecode|awk '/Serial Number:/{print $NF;exit}‘

统计词频

awk '{a[$0]++}END{for(i in a){print i,a[i]}}' a.txt

类似uniq功能

awk '! a[$0]++' a.txt

Awk – 文本处理利器 (续)

杨辉三角

#!/usr/bin/awk -fBEGIN { yan[1,0] = 1; for (i = 2; i <= int(ARGV[1]); i++) { yan[i,0] = 1; yan[i,i-1] = 1; for (j = i-2; j > 0; j--) yan[i,j] = yan[i-1,j-1]
+ yan[i-1,j] } # output for (i = 1; i <= int(ARGV[1]); i++) { for (j = 0; j < i; j++) printf("%d ", yan[i,j]); print }}

#Usage:

# $ ./test.awk 10

head,tail

功能:取一个文件的头若干行或者尾部的若干行。

常用选项:

-n num:指定选取的行数

-f:tail的选项,定时输出文件的最后若干行。

使用举例

tail和head常用来分析日志或者对大规模数据抽取一小部分

tail –f example.log

watch -n 1 head url.lst

diff,cmp,diff3,sdiff,comm

功能:

diff:按行比较两个文件的不同

cmp:按字节比较两个文件的不同

diff3:按行比较三个文件的不同

sdiff:输出两个文件的合集。输出文件中两个文件原本的行在同一行中不同列

comm:快速的比较两个已经排过序的文件,输出两个文件的合集,交集,或任何单独的部分

diff常用选项

常用选项。主要介绍diff的各个选项

-b 忽略两行行尾空格,以及空格个数的区别

-E 忽略tab和空格间的区别

-w 完全忽略所有空格类字符

-B 忽略空行

-I 忽略大小写

--normal以normal形式输出不同行。即指输出不同的行

-c 以context形式输出不同行。包含不同行的上下文

find,locate

功能:查找文件。find将在目录树中查找和用户指定模式相符合的文件。locate则是通过在locate的数据库中查找,locate 的数据库由updatedb程序负责维护。

常用选项:

-name:指定要查找的文件名

-perm:指定要查找文件的权限

-size:指定要查找文件的大小范围

-mtime:指定查找修改时间在n天以内的文件。

exec command:将find命令查找到的文件作为command命令的参数

使用举例:

find . -mtime –1:查找在最近一天内被修改的文件

find . -name b.cpp -exec mv \{\} a.cpp \;

sort

功能:对文件中的各行进行排序。

sort排序是根据从输入行抽取的一个或多个关键字进行比较来完成的。缺省情况下以整行为关键字按ASCII字符顺序进行排序。

常用选项

- m 若给定文件已排好序,合并文件。

- c 检查给定文件是否已排好序。

- u 对排序后认为相同的行只留其中一行。

- d 按字典顺序排序,仅比较字母、数字、空格和制表符。

- r 按逆序输出排序结果。

- b 在每行中寻找排序关键字时忽略前导的空格和制表符。

- t separator 指定字符separator作为字段分隔符。

-k,pos1,[pos2]:以pos1到pos2中间的字符为键值

使用举例

cat words | uniq –c | sort –k 1,1 –n –r 将一批词按照出现频次有高到低排序

uniq,join,cut,paste

cut功能:用来从标准输入或文本中剪切指定列或者域

常用选项:

-c:指定剪切字符数

-f:field 指定剪切指定域数

-d:delimit 指定除空格和tab外的域分隔符

使用举例:

cut –d : -f 3 example.txt

who –u|cut –c1-8

paste功能:将两个文件按行粘贴在不同的列中。是cut的反向操作。

dd

拷贝二进制文件,

格式:

count=BLOCKS 只拷贝BLOCKS个数据块

ibs=BYTES 一次读入的数据量

if=FILE 输入文件

obs=BYTES 一次写出的数据量

of=FILE 输出文件

seek=BLOCKS 输出文件跳过BLOCKS个数据块

skip=BLOCKS 输入文件跳过BLOCKS个数据块

time dd if=/dev/zero of=test bs=1024k count=1024 查看系统io性能

wget

功能:支持使用FTP和HTTP协议,从其他主机上下载所需要的文件

常用选项:

-r:递归的下载目录以及它的子目录和所有文件

-nH:不创建以目标主机域名为目录名的目录,将目标主机的目录结构直接下到当前目录下

--cut-dir=[number]不在本地机器上建立的目录层数

-m, --mirror自动开启适合用来镜像站点的选项

-A, --accept=LIST允许下载的文件类型列表

-R, --reject=LIST拒绝继续下载的文件类型列表

-D, --domains=LIST允许继续扩展的站点列表

--tries=[number]自动重连的次数

-c:断点续传

--debug:使用这个选项可以看到更多wget下载文件过程中的调试信息,比如下载一个http文件时所发送和接收的http包头的格式

--timeout=SECONDS控制wget读超时时间,缺省为900秒

Wget –nH –cut-dir=1 ftp://*:*@test.baidu.com/
wget “http://www.sina.com”

参考资料

Man

正则表达式之道

Sed与awk

Advanced Bash-Scripting Guide
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: