分类 Linux系统运维 下的文章

apache URL 二级域名重写一级域名

将 www.firefoxbug.net 重写成 firefoxbug.net
[cc lang="c"]

DocumentRoot /var/www/firefoxbug
ServerName www.firefoxbug.net
ServerAlias firefoxbug.net
ErrorLog logs/firefoxbug.net-error_log
CustomLog logs/firefoxbug.net-access_log common
RewriteEngine on
rewriteCond %{http_host} ^www.firefoxbug.net [NC]
rewriteRule ^/(.*)$ http://firefoxbug.net/$1 [R=301,L]

[/cc]

RewriteEngine   on
rewriteCond   %{http_host}   ^www.firefoxbug.net  [NC]
rewriteRule   ^/(.*)$  http://firefoxbug.net/$1  [R=301,L]

Stopped (tty output)

问题描述:


在一个shell脚本里,执行了需要I/O操作的程序,一旦把这个shell脚本放在后台执行,就会出现这个错误!

问题原因:


This signal is most commonly generated when a process cannot write to the controlling terminal

because it has been placed into the process background

问题解决:


网上说可以用 ./script < /dev/null &,但是我的脚本需要交互,所以还是挂了。

awk基础学习

awk 处理流的形式也是一行一行的,读取一行然后按照指定的模式进行处理,处理完成后默认输出到终端。

awk [-F fild:separator] 'command' filename
[-F fild-separator ]是可选的,awk默认以空格作为缺省的分隔符号,在脚本中可以通过FS=“X”来设定,X是任意分割符。
表达式匹配的特殊字符
\ ^ $ . [ ] | ( ) * + ?

awk 内置变量


ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk 浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行- F 选项
NF 浏览记录的域个数,用$NF可以表示最后一个域
NR 已读的记录数
OFS 输出域分隔符,OFS="#",输出分隔符就是#
ORS 输出记录分隔符
RS 控制记录分隔符

awk的正则表达式在//里面,模式匹配的sed差不多
找到所有含有root的行,打印第一个域
awk -F : '/root/{print $1}' /etc/passwd

找到行首是root的行,打印第一个域
awk -F : '/^root/{print $1}' /etc/passwd

用~来进行字段匹配,第一个域是root的行
awk -F : '$1~/root/' /etc/passwd
找到第一个域不是root的行
awk -F : '$1!~/root/' /etc/passwd

用print的时候,不同参数之间用逗号作分割符号,则输出以空格作为分割符号;若以空格作为参数分割符号,输出被不存在分隔符号
echo "etc/fire/test.c" | awk -F / '{print $1,$2,$3}'  ==>> home fire test.c
echo "etc/fire/test.c" | awk -F / '{print $1 $2 $3}'  ==>> homefiretest.c

开始结束都加hello,中间打印第一个域
awk -F: 'BEGIN{print "......hello.......\n"} {print $1} END{print ".........hello........\n"}' /etc/passwd

使用if语句进行匹配


找出第一个域是root的行,注意不能写成=,如果写出=,那么就把所有行的第一个域都赋值为root,所有行都匹配
awk -F: '{if($1=="root")} print $0' /etc/passwd

找出第三个域值是32的行
awk -F: '{if($3=="32") print $0}' /etc/passwd

不等于
找出第一个域不是root的行
awk -F: '{if($1!="root") print $0}' /etc/passwd


找出第一个域是root并且第五个域也是root的行
awk -F: '{if($1=="root"&&$5=="root") print $0}' /etc/passwd

NF:每行记录域的总个数
awk -F: '{print NF}' /etc/passwd

NR:已读记录域的数目
awk -F: '{print NR}' /etc/passwd

每行首加总域数和已读域数
awk -F: '{print NF,NR,$0}' /etc/passwd

在保证一行的域大于0,一个域是root的情况下,打印所在行号和行
awk -F: '{if(NF>0 && $1=="root") print NR,$0}' /etc/passwd

显示当前目录的名字,用$NF来显示最后一个域
pwd | awk -F / '{print $NF}'
显示一个目录的文件名字
echo "/home/firefoxbug/test.c" | awk -F / '{print $NF}'

找到第一个域是root行,并把第三个域加3,第四个域加4
可以用{}对匹配的行进行操作,若要执行多条语句,用;分割
awk -F: '{if($1=="root"){$3=$3+3;$4=$4+4;print $0}}' /etc/passwd

在每行最后添加一个域,域值是第三个域值和第四个域值的和
awk -F: '{$(NF+1)=$3+$4;print $(NF)}' /etc/passwd

统计当前目录下所有文件长度,首先排除目录,然后求得ls -l 的第五个域总和
ls -l | grep '^[^d]' | awk '{print $5;total=total+$5} END{print total}'

awk的printf函数,printf函数用法和C语言类似
awk 'BEGIN{printf ("%s\n","hello")}'

awk命令中传递参数
awk '模式' 变量=值 filename
比如查看 df -k 第四个域大于TARGET的项,其中TARGET是用户指定的
df -k | awk '{ if($4>TARGET) {printf ("%s : %d\n",$6,$4) } }' TARGET=650000

查看/etc/passwd下第一个域是USER的行,其中USER由用户指定
awk -F : '{if ($1==USER) {printf ("HAVE %s\n",$1) }}' USER=root /etc/passwd

trap linux

trap命令用于指定在接收到信号后将要采取的行动,trap命令的参数分为两部分,前一部分是接收到指定信号时将要采取的行动,后一部分是要处理的信号名.

信     号

说     明

HUP(1)

挂起,通常因终端掉线或用户退出而引发

INT(2)

中断,通常因按下Ctrl+C组合键而引发

QUIT(3)

退出,通常因按下Ctrl+\组合键而引发

ABRT(6)

中止,通常因某些严重的执行错误而引发

ALRM(14)

报警,通常用来处理超时

TERM(15)

终止,通常在系统关机时发送


一. trap捕捉到信号之后,可以有三种反应方式:
  1. 执行一段程序来处理这一信号
  2. 接受信号的默认操作
  3. 忽视这一信号

二. trap对上面三种方式提供了三种基本形式:
第一种形式的trap命令在shell接收到signal list清单中数值相同的信号时,将执行双
引号中的命令串:
trap 'commands' signal-list
trap "commands" signal-list

第二种形式的trap命令,为了恢复信号的默认操作:
trap signal-list

第三种形式的trap命令允许忽视信号:
trap " " signal-list

在第一种形式中,执行命令,对于双引号和单引号是有区别的。

#/bin/bash

#忽略信号
#trap " " 2

#双引号,shell第一次设置信号的时候就执行命令和变量的替换,时间不变
trap "echo `date`:can not terminate by ctrl+C" 2		

#单引号,要在shell探测到信号来的时候才执行命令和变量的替换,时间一直变
trap 'echo `date`:can not terminate by ctrl+C' 2		

while [ 1 ]
do
	echo -n "input a num : "
	read num 
	if [ $num -eq -1 ]
	then
		echo "bye"
		break
	fi
	echo "you have enter $num"
done

shell执行过程简介

[root@fire cgi-bin]# export TEST="Hello
> Wolrd
> From
> Linux"
[root@fire cgi-bin]# echo $TEST 
Hello Wolrd From Linux
[root@fire cgi-bin]# echo "$TEST" 
Hello
Wolrd
From
Linux
[root@fire cgi-bin]# echo '$TEST'
$TEST

上面是测试,一直以来对hard quote(单引号)和soft quote(双引号),弄得不是很懂,今早又碰到这个问题。

下面来解释上面的测试代码:

首先从根本出发,shell的任务的就是解释用户的输入,将一大堆的字符串做处理。处理成

command_program options  arguments

这样的格式,说白了就是把一个整的字符串分割成一个一个的字段("word"),那么shell是通过什么分割的呢?通过把<space>,<enter>,<tabs>这三种作为分隔符,拆分成字段。而shell是通过最后用户输入一个<enter>键来标明用户输入的结束,一旦处理到<enter>键,shell就得到了通知:用户已经输入完成了,我可以执行命令去了。之后shell根据默认的IFS处理,进行变量的替换之类的工作,最后提交给程序执行。

看上面的第一个命令

[root@fire cgi-bin]# export TEST="Hello
> Wolrd
> From
> Linux"

因为soft quote能屏蔽<enter>,<enter>键所产生的CR字符不会被shell当作结束符,所以shell继续等待用户的输入,等到用户输入后面的双引号,再输入<enter>键,这时候shell读到了CR字符,就知道用户输入的结束了,于是就开始执行命令。这个时候TEST里面的内容其实是:

Hello<CR>World<CR>From<CR>Linux

注意“Linux”后面是没有<CR>的,之所以会有换行,是因为echo执行结束后会自动送入一个<CR>!

再看第二条命令:

echo $TEST

这时候没有hard quote或者soft quote,shell得到的命令变成

echo Hello<CR>World<CR>From<CR>Linux

现在再去看shell的执行过程,shell就是“把一个整的字符串拆分成字段,字段分割的标识是<space>,<enter>,<tabs>,然后根据默认的IFS处理”,shell读到<CR>,通通都按照默认的IFS(空格)处理。所以处理的结果就可想而知了:所有的<CR>变成了<space>。最后得到的最终命令,按照

command_program options  argumentscommand_program 就是 echo ,options 是无 ,arguments 就是 Hello World From Linux

再来看第三条命令

echo "$TEST"

这个存在soft quote,shell得到命令就是

echo "Hello<CR>World<CR>From<CR>Linux"

这里shell不能处理什么,soft quote里面就是一个参数,最终的命令是

command_program 就是 echo ,options 是无 ,arguments 就是 Hello<CR>World<CR>From<CR>Linux

最后看第四条命令

echo '$TEST'

这个最简单, TEST变量在hard quote里面,所有的meta都被屏蔽了,所以按照最终的命令就是

command_program 就是 echo ,options 是无 ,arguments 就是 $TEST

自己动手学TCP/IP–http协议(http报文格式)

HTTP(HyperText Transport Protocol,超文本传送协议)

HTTP请求报文


http请求数据包的格式:头部(request line + header)+  数据(data)

头部和数据包体通过一个空行来隔开,头部的格式主要包括请求行+请求头部。如下图

HTTP请求头

请求行


请求行由请求方法字段URL字段HTTP协议版本字段3个字段组成,它们用空格分隔如:

GET /index.html HTTP/1.1。

HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。这里介绍最常用的GET方法和POST方法。

GET方式:在URL里面就说明要请求的资源,URL里面包含参数,“?”后面就是参数,而“?”前面就是URL的结束。“?ip=192.168.156.11&active=on”这种就是GET方式的包,而服务器把客户端请求的内容在数据段里面发回给客户端。

POST方式:传输的数据不在URL里面出现,而是在数据段里面出现。但是请求头部多了Content-Type和Content-Length两个字段。

请求头部


请求头部由(关键字:<空格>值)对组成,每行一对,关键字和值用英文冒号“:<空格>”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:

User-Agent:产生请求的浏览器类型。

Accept:客户端可识别的内容类型列表。

Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。

下面是GET包的一个例子:传输的数据在URL里

再看看POST包的例子:传输的数据在数据段里面


HTTP响应报文


HTTP响应也由两个个部分组成,分别是:响应头(状态行+消息报头)+响应正文

状态行格式如下:

HTTP-Version Status-Code Reason-Phrase CRLF

HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。

1xx:指示信息--表示请求已接收,继续处理。

2xx:成功--表示请求已被成功接收、理解、接受。

3xx:重定向--要完成请求必须进行更进一步的操作。

4xx:客户端错误--请求有语法错误或请求无法实现。

5xx:服务器端错误--服务器未能实现合法的请求。

下面是http响应包的例子

嵌入式boa服务器搭建和移植

1.先下载源码 http://www.boa.org/ ==> boa-0.94.13.tar.g

2.tar -xvf boa-0.94.13.tar.g

3./configure

4.修改Makefile

CC =or32-linux-gcc

CPP = or32-linux-gcc–E

5.修改boa.c,注释下面几行

if (setuid(0) != -1) {
DIE("icky Linux kernel bug!");
}改为/*if (setuid(0) != -1) {
DIE("icky Linux kernel bug!");
}*/

6.修改文件compat.h

#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
修改成
#define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff

7.make 编译,这时候就会生成一个boa的可执行文件

boa的配置文件是boa.conf,大概的配置是这样的:

Port 80   //服务访问端口

User 0
Group 0   

ErrorLog /var/log/boa/error_log //错误日志地址
AccessLog /var/log/boa/access_log  //访问日志文件

DocumentRoot /var/www  //HTML文档的主目录

UserDir public_html  //

DirectoryIndex index.html  //默认访问文件

DirectoryMaker /usr/lib/boa/boa_indexer

KeepAliveMax 1000   //一个连接所允许的HTTP持续作用请求最大数目

KeepAliveTimeout 10  //HTTP持续作用中服务器在两次请求之间等待的时间数,以秒为单位

MimeTypes /etc/mime.types  //指明mime.types文件位置

DefaultType text/plain  //文件扩展名没有或未知的话,使用的缺省MIME类型

CGIPath /bin:/usr/bin:/usr/local/bin   //提供CGI程序的PATH环境变量值

Alias /doc /usr/doc    //为路径加上别名

ScriptAlias /cgi-bin/ /var/www/cgi-bin/ //输入站点和CGI脚本位置

对于调试阶段,可以把主机的目录挂载到目标板上面,这样就方便调试。

假设主机的NFS共享目录是/NFS,在NFS下面建立一个www的文件夹,然后在www的文件夹下面建立images,cig-bin目录,还有一个index.html,可以随便找一个主页就可以了。在主机上

mkdir /NFS/www

mkdir /NFS/www/images

mkdir /NFS/www/cgi-bin

cp <dir>/index.html /NFS/www/

然后在板子上面建立/var/www的目录

mkdir /var/www

mount -t nfs -o nolock <主机IP>:/NFS/www /var/www //挂载目标www

板子上建立日志存放目录,在板子上:

mkdir /var/log

mkdir /var/log/boa

对于boa配置文件的移植,可以把主机上的boa.conf拷贝到主机的NFS共享目录/NFS/www下面。

对于mime.types,直接用主机上/etc/mime.types就行了,拷贝到/NFS/www下面。

对于boa可执行文件,拷贝到/NFS/www/下面。

在主机上:

cp /etc/mime.types /NFS/www/

cp <boa dir>/boa.conf /NFS/www/

cp <boa dir>/src/boa  /NFS/www/

然后再在板子上把上面共享的文件拷贝到自己系统上,注意此时只要对/var/www操作就行了,在主机上:

cp /var/www/mime.types /etc/mime.types

mkdir /etc/boa

cp /var/www/boa.conf  /etc/boa/boa.conf

cp /var/www/boa /sbin/boa

/sbin/boa 启动boa服务器

在浏览器里输入板子的IP就可以测试了。

find+*的问题

不久前做移植的时候想把某个目录下的C文件都找出来,然后拷贝下,结果一直报错,我用的是*.c作为pattern。今天看论坛的时候知道为什么了。

$ ls

test2.c  test.c  test.txt

目录下有两个.c文件,还有一个.txt文件

$ find . -name *.c

error : find: 路径必须在表达式之前: test.c
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

$ find . -name *.txt

./test.txt

$ find . -name "*.c"

./test2.c
./test.c

原因:

若是不加引号 $ find . -name *.txt 成功,而不加引号的 $ find . -name*.c 出错了,得看看shell是怎么执行这句话的,首先shell读到了 *.txt 和 *.c,因为 * 是shell认为的meta (理解为特殊字符),所以就先解释*txt 先执行成 test.txt,传递给find,find就去执行自己的操作,根据pattern发现符合要求。而 *.c 被shell翻译成了test.c和test2.c,这时候命令就变成了 find . -name test.c test2.c 这就出错了!因为find -name 选项后面只能支持一个文件的搜索。所以对于test2.c是前面没有选项,就报错了!

对于有引号的 find . -name "*.c",shell读到"*.c"的时候,会当作参数处理,传递给find,find之后会自己处理 *.c,可以查看 man find ,里面有

The metacharacters (`*', `?', and `[]') match a `.'

CentOS 相关服务

daemon和service没什么大的区别,基本上可以等价。

daemon的分类


1.stand_alone


这些服务常驻内存里面,随时能迅速响应客户端的要求。比如www服务(httpd),FTP的daemon的(vsftpd)。

stand_alone的启动方式:linux上服务启动基本上的都是脚本启动比较多,脚本会对环境测试,配置文件的分析,以及管理服务,比如启动服务,重启服务,关闭服务,查看服务状态之类的。对于stand_alone的启动方式一般都在/etc/init.d/下面,这里面有很多系统服务启动脚本,可以进去用vim查看,发现有对于服务状态的控制和环境的测试,还有一点就是读取服务的配置文件,那么这些服务的配置文件在哪里呢?就在 /etc/sysconfig/ 下面,比如比较熟悉的网络配置文件 /etc/sysconfig/network,还有iptables的/etc/sysconfig/iptables相关的规则的描述。stand_alone服务启动一般都是以

/etc/init.d/xxx start|stop|restart|status

也可以是

service xxx  start|stop|restart|status

service 是一个脚本,它能帮用户分析所要启动的stand_alone脚本,,然后根据输入的参数去读取/etc/init.d/*下的脚本。

2。super daemon


与stanld_alone daemon不同的是super daemon。super daemon本身是一种stand_alone,只是它所调用的服务不是,它所调用的服务默认情况下不是驻留在内存中的,而是需要服务的时候再启动,把相应的服务加载到内存里。super daemon采取的是一种统一管理服务的形式,由一个daemon管理很多服务,这个daemon就是xinetd,有客户端需要连接的时候,xinetd就会去调用响应的服务,加载到内存去响应连接。我们可以查看/etc/xinetd.d/,下面的文件就是会被xinetd调用的服务文件配置,比如tftp,你可以用vim打开它,然后编辑相关的属性,重启xinetd就会重新读取/etc/xinetd.d/tftp文件。那么xinetd这个daemon在哪里呢?就在/etc/init.d/下面,前面说了,xinetd也是一个stand_alone类型的daemon,开机就启动。xinetd它也有它默认的配置文件,就是/etc/xinetd.conf,对于调用的服务,如果在/etc/xinetd.d/下面没有配置文件,就默认会以/etc/xinetd.conf的配置启动。所有xinetd调用的服务都由xinetd统一进行管理,

/etc/init.d/xinetd start|stop|restart|status 

ssh自动登入脚本

#!/usr/bin/expect -f

if { $argc < 3 } {
puts stderr "Usage: $argv0 IPAdress Login OldPasswd"
exit
}

set IPADDR [lindex $argv 0]
set LOGIN [lindex $argv 1]
set OLD_PW [lindex $argv 2]

set timeout -1 

#stty -echo

spawn ssh $IPADDR -l $LOGIN
expect {
    "*assword:*"  {
        send "$OLD_PW\r"
        exp_continue
    } "*ast login:*" {
        interact
        exit 0
    } timeout {
        send_user "connection to $IPADDR timeout!\n"
        exit 1
    } "*incorrect*" {
        send_user "password incorrect!\n"
        exit 2
    } "*ermission*" {  #for LINUX ssh
        send_user "password Error!\n"
        exp_continue
        exit 2
    } eof {
        exit 3
    }
}

使用方法 : ./my_ssh.sh192.168.156.10 root 123456

bash编程中反引号

反引号(`   `):能把shell中一个命令的标准输出嵌入到原来的位置!也叫做是命令替换,于它等价的是$(cmd)

#!/bin/bash

ls -l /
`ls -l / | awk {print $5}`

看上面的脚本,第一个输出是正常的,第二个就不正常的,但是第三个也不正常了。

# ls -l / | awk {print $5}

这个命令能列出文件的大小,返回的值就是文件的大小,上面说了:反括弧的功能就是把里面的命令的标准输出嵌入到原来位置中,也就是说awk之后把返回的文件大小当作另一个命令来解释,所以会提示:

./test5.sh:行4: $'\346\200\273\347\224\250\351\207\217': 未找到命令
awk: cmd. line:1: {print
awk: cmd. line:1: ^ unexpected newline or end of string

再来看
#!/bin/bash

for file in `ls -l /home/fire`
do
        echo "$file"
done

看看脚本执行的过程:

对于反括弧里面的内容先执行,那么就是以 ls -l 列出所有文件信息,然后插入到原来的位置,这时,for 就开始对了`ls -l /home/fire`列出的文件信息当作列表,以 IFS = “空格” 进行分割,列出信息。

还有异议吗?再来看段代码:

#!/bin/bash
echo the time is $(date)
$(date)

第一个输出是正确的,第二个就错误了。原因还是上面的,把$(date)返回的时间值,插入到原来的位置,当shell解释的时候就是对时间值当作命令解释,所以就出错了!
./test5.sh:行4: $'2012\345\271\264': 未找到命令

总之对于反括弧或者$(),第一步就是执行里面的命令,把命令执行的标准输出插入到原来的位置,第二步就是执行替换后的语句!

linux shell 正则表达式(BREs,EREs,PREs)差异比较--<转>

正则表达式:在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。这些是正则表达式的定义。 由于起源于unix系统,因此很多语法规则一样的。但是随着逐渐发展,后来扩展出以下几个类型。了解这些对于学习正则表达式。

一、正则表达式分类:

1、基本的正则表达式(Basic Regular Expression 又叫 Basic RegEx  简称 BREs)

2、扩展的正则表达式(Extended Regular Expression 又叫 Extended RegEx 简称 EREs)

3、Perl 的正则表达式(Perl Regular Expression 又叫 Perl RegEx 简称 PREs)

说明:只有掌握了正则表达式,才能全面地掌握 Linux 下的常用文本工具(例如:grep、egrep、GUN sed、 Awk 等) 的用法

二、Linux 中常用文本工具与正则表达式的关系

常握 Linux 下几种常用文本工具的特点,对于我们更好的使用正则表达式是很有帮助的

  • grep , egrep 正则表达式特点:

1)grep 支持:BREs、EREs、PREs 正则表达式

grep 指令后不跟任何参数,则表示要使用 ”BREs“

grep 指令后跟 ”-E” 参数,则表示要使用 “EREs“

grep 指令后跟 “-P” 参数,则表示要使用 “PREs”

2)egrep 支持:EREs、PREs 正则表达式

egrep 指令后不跟任何参数,则表示要使用 “EREs”

egrep 指令后跟 “-P” 参数,则表示要使用 “PREs”

3)grep 与 egrep 正则匹配文件,处理文件方法

a. grep 与 egrep 的处理对象:文本文件

b. grep 与 egrep 的处理过程:查找文本文件中是否含要查找的 “关键字”(关键字可以是正则表达式) ,如果含有要查找的 ”关健字“,那么默认返回该文本文件中包含该”关健字“的该行的内容,并在标准输出中显示出来,除非使用了“>” 重定向符号,

c. grep 与 egrep 在处理文本文件时,是按行处理的


  • sed 正则表达式特点

1)sed 文本工具支持:BREs、EREs

sed 指令默认是使用”BREs”

sed 命令参数 “-r ” ,则表示要使用“EREs”

2)sed 功能与作用

a. sed 处理的对象:文本文件

b. sed 处理操作:对文本文件的内容进行 — 查找、替换、删除、增加等操作

c. sed 在处理文本文件的时候,也是按行处理的


  • Awk(gawk)正则表达式特点

1)Awk 文本工具支持:EREs

awk 指令默认是使用 “EREs”

2)Awk 文本工具处理文本的特点

a. awk 处理的对象:文本文件

b. awk 处理操作:主要是对列进行操作


三、常见3中类型正则表达式比较
字符 说明 Basic RegEx Extended RegEx python RegEx Perl regEx
转义 \ \ \ \
^ 匹配行首,例如’^dog’匹配以字符串dog开头的行(注意:awk 指令中,’^'则是匹配字符串的开始) ^ ^ ^ ^
$ 匹配行尾,例如:’^、dog$’匹配以字符串 dog 为结尾的行(注意:awk 指令中,’$'则是匹配字符串的结尾) $ $ $ $
^$ 匹配空行 ^$ ^$ ^$ ^$
^string$ 匹配行,例如:’^dog$’匹配只含一个字符串 dog 的行 ^string$ ^string$ ^string$ ^string$
\< 匹配单词,例如:’\<frog’ (等价于’\bfrog’),匹配以 frog 开头的单词 \< \< 不支持 不支持(但可以使用\b来匹配单词,例如:’\bfrog’)
\> 匹配单词,例如:’frog\>’(等价于’frog\b ‘),匹配以 frog 结尾的单词 \> \> 不支持 不支持(但可以使用\b来匹配单词,例如:’frog\b’)
\<x\> 匹配一个单词或者一个特定字符,例如:’\<frog\>’(等价于’\bfrog\b’)、’\<G\>’ \<x\> \<x\> 不支持 不支持(但可以使用\b来匹配单词,例如:’\bfrog\b’
() 匹配表达式,例如:不支持’(frog)’ 不支持(但可以使用\(\),如:\(dog\) () () ()
\(\) 匹配表达式,例如:不支持’(frog)’ \(\) 不支持(同()) 不支持(同()) 不支持(同())
匹配前面的子表达式 0 次或 1 次(等价于{0,1}),例如:where(is)?能匹配”where” 以及”whereis” 不支持(同\?)
\? 匹配前面的子表达式 0 次或 1 次(等价于’\{0,1\}’),例如:’where\(is\)\? ‘能匹配 “where”以及”whereis” \? 不支持(同?) 不支持(同?) 不支持(同?)
? 当该字符紧跟在任何一个其他限制符(*, +, ?, {n},{n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个”o”,而 ‘o+’ 将匹配所有 ‘o’ 不支持 不支持 不支持 不支持
. 匹配除换行符(’\n’)之外的任意单个字符(注意:awk 指令中的句点能匹配换行符) . .(如果要匹配包括“\n”在内的任何一个字符,请使用:’(^$)|(.) . .(如果要匹配包括“\n”在内的任何一个字符,请使用:’ [.\n] ‘
* 匹配前面的子表达式 0 次或多次(等价于{0, }),例如:zo* 能匹配 “z”以及 “zoo” * * * *
\+ 匹配前面的子表达式 1 次或多次(等价于’\{1, \}’),例如:’where\(is\)\+ ‘能匹配 “whereis”以及”whereisis” \+ 不支持(同+) 不支持(同+) 不支持(同+)
+ 匹配前面的子表达式 1 次或多次(等价于{1, }),例如:zo+能匹配 “zo”以及 “zoo”,但不能匹配 “z” 不支持(同\+) + + +
{n} n 必须是一个 0 或者正整数,匹配子表达式 n 次,例如:zo{2}能匹配 不支持(同\{n\}) {n} {n} {n}
{n,} “zooz”,但不能匹配 “Bob”n 必须是一个 0 或者正整数,匹配子表达式大于等于 n次,例如:go{2,} 不支持(同\{n,\}) {n,} {n,} {n,}
{n,m} 能匹配 “good”,但不能匹配 godm 和 n 均为非负整数,其中 n <= m,最少匹配 n 次且最多匹配 m 次 ,例如:o{1,3}将配”fooooood” 中的前三个 o(请注意在逗号和两个数之间不能有空格) 不支持(同\{n,m\}) {n,m} {n,m} {n,m}
x|y 匹配 x 或 y,例如: 不支持’z|(food)’ 能匹配 “z” 或”food”;’(z|f)ood’ 则匹配”zood” 或 “food” 不支持(同x\|y) x|y x|y x|y
[0-9] 匹配从 0 到 9 中的任意一个数字字符(注意:要写成递增) [0-9] [0-9] [0-9] [0-9]
[xyz] 字符集合,匹配所包含的任意一个字符,例如:’[abc]‘可以匹配”lay” 中的 ‘a’(注意:如果元字符,例如:. *等,它们被放在[ ]中,那么它们将变成一个普通字符) [xyz] [xyz] [xyz] [xyz]
[^xyz] 负值字符集合,匹配未包含的任意一个字符(注意:不包括换行符),例如:’[^abc]‘ 可以匹配 “Lay” 中的’L'(注意:[^xyz]在awk 指令中则是匹配未包含的任意一个字符+换行符) [^xyz] [^xyz] [^xyz] [^xyz]
[A-Za-z] 匹配大写字母或者小写字母中的任意一个字符(注意:要写成递增) [A-Za-z] [A-Za-z] [A-Za-z] [A-Za-z]
[^A-Za-z] 匹配除了大写与小写字母之外的任意一个字符(注意:写成递增) [^A-Za-z] [^A-Za-z] [^A-Za-z] [^A-Za-z]
\d 匹配从 0 到 9 中的任意一个数字字符(等价于 [0-9]) 不支持 不支持 \d \d
\D 匹配非数字字符(等价于 [^0-9]) 不支持 不支持 \D \D
\S 匹配任何非空白字符(等价于[^\f\n\r\t\v]) 不支持 不支持 \S \S
\s 匹配任何空白字符,包括空格、制表符、换页符等等(等价于[ \f\n\r\t\v]) 不支持 不支持 \s \s
\W 匹配任何非单词字符 (等价于[^A-Za-z0-9_]) \W \W \W \W
\w 匹配包括下划线的任何单词字符(等价于[A-Za-z0-9_]) \w \w \w \w
\B 匹配非单词边界,例如:’er\B’ 能匹配 “verb” 中的’er’,但不能匹配”never” 中的’er’ \B \B \B \B
\b 匹配一个单词边界,也就是指单词和空格间的位置,例如: ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的’er’ \b \b \b \b
\t 匹配一个横向制表符(等价于 \x09和 \cI) 不支持 不支持 \t \t
\v 匹配一个垂直制表符(等价于 \x0b和 \cK) 不支持 不支持 \v \v
\n 匹配一个换行符(等价于 \x0a 和\cJ) 不支持 不支持 \n \n
\f 匹配一个换页符(等价于\x0c 和\cL) 不支持 不支持 \f \f
\r 匹配一个回车符(等价于 \x0d 和\cM) 不支持 不支持 \r \r
\\ 匹配转义字符本身”\” \\ \\ \\ \\
\cx 匹配由 x 指明的控制字符,例如:\cM匹配一个Control-M 或回车符,x 的值必须为A-Z 或 a-z 之一,否则,将 c 视为一个原义的 ‘c’ 字符 不支持 不支持 \cx
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长,例如:’\x41′ 匹配 “A”。’\x041′ 则等价于’\x04′ & “1″。正则表达式中可以使用 ASCII 编码 不支持 不支持 \xn
\num 匹配 num,其中 num是一个正整数。表示对所获取的匹配的引用 不支持 \num \num
[:alnum:] 匹配任何一个字母或数字([A-Za-z0-9]),例如:’[[:alnum:]] ‘ [:alnum:] [:alnum:] [:alnum:] [:alnum:]
[:alpha:] 匹配任何一个字母([A-Za-z]), 例如:’ [[:alpha:]] ‘ [:alpha:] [:alpha:] [:alpha:] [:alpha:]
[:digit:] 匹配任何一个数字([0-9]),例如:’[[:digit:]] ‘ [:digit:] [:digit:] [:digit:] [:digit:]
[:lower:] 匹配任何一个小写字母([a-z]), 例如:’ [[:lower:]] ‘ [:lower:] [:lower:] [:lower:] [:lower:]
[:upper:] 匹配任何一个大写字母([A-Z]) [:upper:] [:upper:] [:upper:] [:upper:]
[:space:] 任何一个空白字符: 支持制表符、空格,例如:’ [[:space:]] ‘ [:space:] [:space:] [:space:] [:space:]
[:blank:] 空格和制表符(横向和纵向),例如:’[[:blank:]]’ó’[\s\t\v]‘ [:blank:] [:blank:] [:blank:] [:blank:]
[:graph:] 任何一个可以看得见的且可以打印的字符(注意:不包括空格和换行符等),例如:’[[:graph:]] ‘ [:graph:] [:graph:] [:graph:] [:graph:]
[:print:] 任何一个可以打印的字符(注意:不包括:[:cntrl:]、字符串结束符’\0′、EOF 文件结束符(-1), 但包括空格符号),例如:’[[:print:]] ‘ [:print:] [:print:] [:print:] [:print:]
[:cntrl:] 任何一个控制字符(ASCII 字符集中的前 32 个字符,即:用十进制表示为从 0 到31,例如:换行符、制表符等等),例如:’ [[:cntrl:]]’ [:cntrl:] [:cntrl:] [:cntrl:] [:cntrl:]
[:punct:] 任何一个标点符号(不包括:[:alnum:]、[:cntrl:]、[:space:]这些字符集) [:punct:] [:punct:] [:punct:] [:punct:]
[:xdigit:] 任何一个十六进制数(即:0-9,a-f,A-F) [:xdigit:] [:xdigit:] [:xdigit:] [:xdigit:]

四、三种不同类型正则表达式比较

注意: 当使用 BERs(基本正则表达式)时,必须在下列这些符号前加上转义字符(’\'),屏蔽掉它们的 speical meaning  “?,+,|,{,},(,)” 这些字符,需要加入转义符号”\”

注意:修饰符用在正则表达式结尾,例如:/dog/i,其中 “ i “ 就是修饰符,它代表的含义就是:匹配时不区分大小写,那么修饰符有哪些呢?常见的修饰符如下:

g   全局匹配(即:一行上的每个出现,而不只是一行上的第一个出现)
s    把整个匹配串当作一行处理
m    多行匹配
i    忽略大小写
x    允许注释和空格的出现
U    非贪婪匹配


原文链接:http://archive.cnblogs.com/a/1847287/

NFS 搭建

最近做嵌入式开发的时候,需要NFS加载文件系统,顺便搭建了一个NFS。

NFS:Network File System


功能也就是能把远程网络的文件挂载到NFS Server上,在Server上看来,客户端的挂载的目录就像自己的子目录一样,可以对它操作。所以,对于嵌入式系统的调试是很方便的。

NFS支持的功能很多,所以对应的端口号是不固定的,是随机分配的,但都是小于1024。那么客户机是怎么连接到NFS Server上去的呢?这里有一个RPC的东西来支持。

RPC:(Remote Procedure Call Protocol)


远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
RPC在NFS搭建过程钟的功能就是在Server上分配端口号,可以让客户端能从远程连接上Server。RPC固定采用111端口监听。

- 阅读剩余部分 -

source exec fork 区别

#1.sh
#!/bin/bash

A=B
echo "PID for 1.sh before exec/source/fork ; $$"
export A
echo "1.sh : \$A is $A"
case $1 in 
	exec)
		echo "using exec..."
		exec ./2.sh
		;;
	source)
		echo "using source..."
		. ./2.sh
		;;
	*)
		echo "using fork by default..."
		./2.sh
		;;	
esac 

echo "PID for 1.sh after exec/source/fork : $$"
echo "1.sh : \$A is $A"
#2.sh
#!/bin/bash

echo "PID for 2.sh : $$ "
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh : \$A is $A"

source测试


[root@fire Shell]# ./1.sh source
PID for 1.sh before exec/source/fork ; 8952
1.sh : $A is B
using source...
PID for 2.sh : 8952 
2.sh get $A=B from 1.sh
2.sh : $A is C
PID for 1.sh after exec/source/fork : 8952
1.sh : $A is C

对于参数 source,表示执行2脚本格式是:source 2.sh,由输出可以看出,source的执行就是在本shell中执行,共用原shell的环境变量

fork测试


[root@fire Shell]# ./1.sh 
PID for 1.sh before exec/source/fork ; 9019
1.sh : $A is B
using fork by default...
PID for 2.sh : 9020 
2.sh get $A=B from 1.sh
2.sh : $A is C
PID for 1.sh after exec/source/fork : 9019
1.sh : $A is B

对于普通的./xxx.sh,shell新建了一个子shell(sub-shell),sub-shell继承了父shell的环境变量,仅仅是copy版本而已,子shell里面无论怎么修改变量,在子shell退出之后,子shell的所有资源和变量都被回收。所以是不会影响父shell的。在子shell执行的时候,父shell会处于挂起状态,等待子shell结束返回。

exec测试


PID for 1.sh before exec/source/fork ; 9095
1.sh : $A is B
using exec...
PID for 2.sh : 9095 
2.sh get $A=B from 1.sh
2.sh : $A is C

对于exec也会让行程在同一个shell上执行,只是exec的调用会把原来的shell执行的行程结束了,重新开始另一个行程。