玩转脚本======>SHELL笔记(2012.08.08正则表达式)
最近做的项目需要用shell写脚本文件,大致的看了一下用法,为了掌握,我从昨天开始看shell脚本学习指南(点击链接下载)这本书。最近事情比较多,看书的时间压缩的太少了,看到第二章的时候需要了解正则表达式,推荐一篇文章——正则表达式30分钟入门教程,鸟哥的私房菜第三部分也都包括了,比较容易理解。这部分准备两个星期的空闲时间搞定。今天是8号,20号之前一定要看完。
#################################################################2012.8.8############################################################################
简单性:是一个高级语言,通过它,简洁的表达复杂的操作;
可移植性:脚本无须修改就可以运行在不同的系统上;
开发容易:可以在段时间内完成一个功能强大又好用的脚本;
eg1: who | wc -l ~~~~~~~~~~~~~~~~计算用户个数 who 的输出是 wc的输入
shell的基本元素:
1,命令与参数:
eg2: cd work ; ls -l shishang.c 分号会分隔同一行的多条命令。shell会依次执行这些程序,如果换成&的话,shell将在后台执行前面的命令,不用等到该命令执行完成,就可以继续执行下一个命令。
shell 识别三种命令:内建命令--cd,read,echo,printf,test等;shell函数--可以像命令一样引用;外部命令:
就是由shell脚本所执行的命令--建立一个新的进程,进程为shell的一个副本,在新的进程里,PATH变量目录中,寻找特殊命令,在新的进程里取代执行中的shell程序并且执行,程序完成会直接从终端读取下一条命令,或者执行脚本里的下一条命令。
2,变量:可以分配值。
3,简单的echo输出:移植比较难,转义序列:\a 警示字符 \b 退格 \f 清除屏幕 等.
4,printf输出.
5,基本的I/O重定向:默认情况下,他们会读取标准输入,写入标准输出,并将错误信息标准输出,这类程序常常叫做过滤器(filter),这几个都是终端。I/O重定向是指通过与终端进行交互,或者在脚本文件中修改设置,重新安排从哪里输入或者输出到哪里。
6,重定向与管道:< 改变标准输入 > 改变标准输出 >的符号会新建或者覆盖,>>不会覆盖;
管道:program1 | program2 将前者的标准输出修改为后者的标准输入。虽然 < > 可以把输入与输出连接到文件,不过管道可以把两个以上的执行程中的程序衔接在一起。管道可以使得执行速度比临时文件程序快上10倍。
7,访问shell的脚本参数:who | grep $1 脚本文件中的意思是$1---执行的时候需要一个参数。
8,简单的执行跟踪:set -x 打开跟踪功能,set +x 关闭追踪功能 在脚本文件中也可以添加这两个命令。
当我们对性能要求不高的时候,希望尽快开发出程序并以较高级的方式工作时,使用脚本最佳时机。
##########################2012.08.09#############################################
鸟哥的私房菜:正则表达式(第十二章)linux基础中的基础,也是最难的部分
正则表达式是通过一些特殊字符的排列,用来搜索/替换/删除/一行或者多行字符串,就是用在字符串处理中的“表达式”。
正则表达式以行为单位处理字符串;正则表达式和“通配符“不一样。
~~~基础的正则表达式~~~
-
通过grep选取字符串
grep [-acinv] '搜索字符串' filename
a:在二进制文件中以文本方式搜数据 c:计算找到字符串的次数 i:忽略大小写 n:输出行号 v:反向选择
grep在搜索数据的时候查找一个字符串,是以行为单位进行数据选取的,就是说,加入一个字符串在两行中出现了,这两行显示在屏幕上,其他行丢弃。
除了用于文件搜索之外,常常英语在输入/输出的数据处理中,例如常见的管道命令。
修改语系:# LANG=en # export LANG
-
搜索特定字符串:#grep -n 'the' test.txt
-
利用[ ]搜索字符合集:#grep -n 't[ae]st' test.txt [ ]中不管有几个字符,都代表其中一个字符,如果不想oo前边有g的话 命令用反向选择^ #grep -n '[^g]oo' text.txt 还有其他写法 [^a-z][^0-9]等
-
行首与行尾字符 ^ $ #grep -n '^the' text.txt 表示寻找the在开头的行,不想要开头是英文字母的行就这样写 #grep -n '[^a-zA-Z]' text.txt (注:^在[ ]内表示反向选择,^在[ ]外表示开头字符)要找‘ . ’ 结尾的字符行 #grep -n '\.$' text.txt 加上了转义字符\ 找空白行 ^$ 就行了 #grep -v '^$' text.txt | grep -v '^#' text.txt 把#开头的和空白行都去掉显示,节省了版面。
-
任意一个字符(.)和重复字符(*):(.)表示绝对有一个字符的意思 如果至少有两个o以上怎么写 'ooo*' 即(*)表示重复0个或者1个前面的字符 所以(o*)表示拥有空字符或者一个以上的o。寻找字符开头和结尾都是g的 ‘g*g’ 是不行的,要用‘g.*g’表示,即(.*)表示0个或者多个任意字符。如果想招任意都是数字的行用什么? '[0-9][0-9]*' 就可以了。
-
限定连续重复字符范围{ }:要找出g后边接2--5个o的话怎么写? #grep -n 'g\{2,5\}' text.txt 如果要找两个或者两个以上的goo....g 可以这么使用 ‘gooo*g’ 或者 'go\{2,\}g'。
2.重要特殊字符:
# grep -n \' text.txt 搜索有单引号的那一行;
# . 代表任意一个字符,也一定是一个字符;
# *为重复前一个字符的符号,所以前边必须有一个字符,任意字符则为 .*;
# \{n\} 连续重复n个前一个字符,\{n,\} 连续重复n 个以上前边的字符;
# [^A-Z]代表非大写字母的行,每行都会列出来,应为每一行都有非大写字母;
# 正则表达式vs通配符:ls -l * 代表列出任意文件名的文件 ls -l a* 代表以a开头的文件,在正则表达式中则为:ls | grep -n '^a.*'。
~~~扩展的正则表达式~~~
如果使用扩展表达式,可以这样写 #egrep-v '^$|^#' test.txt ,比之前的例子简单;
-
+ :重复一个或者一个以上的字符 #egrep -n 'go+d' test.txt 代表一个或者一个以上的o;
-
?:0个或者一个字符 'go?d' 即'gd'或者'god';
-
| :或的方式找字符串,‘gd|dog’ 两者其中一个;
-
( ):找出用户组字符串,‘g(la|oo)d’ 搜索glad或者good;
-
!或者<这样的字符不是特殊字符,不用转义符;
~~~格式化显示,sed,awk工具~~~
-
格式化显示:printf \xNN NN为两位数字,可以转换数字成为字符;%ns %nd,多少个字符或者数字
-
sed工具:分析标准输入的数据,数据经过处理之后,再输出到标准输出.sed [acdips] a,新增 c,替换 d,删除 i,插入 p,打印 s,搜索或者替换 # nl ./etc/passwd | sed '2a drink tea' 2行后加了字符,2i的话是之前加;# nl /etc/passwd | sed '2,5c number' 替换2到5行;# nl /etc/paswd | sed -n '2,5p' 仅仅显示2到5行 -n 表示只显示经过sed处理的;# ifconfig eth0 | grep 'inet' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g' 掐头去尾。
-
awk工具:awk倾向于一种一行中分成数个“字段来进行处理” 适合小型的数据。 # awk '条件类型{动作}......' filename 处理每一行字段内的数据,默认的字段分割符为空过或者tab,last可以将登录者取出来,想取出来登录者和IP地址中间用tab分开,# last | awk '{printf $1 “\t” $3}' $0代表一整行数据的意思。 NF每一行拥有的字段数,NR当前awk处理的是第几行的数据,FS当前的分割符号,默认为空格健。# last | awk '{print $1 "\t line: " NR "\t columes: " NF}' , 要查看第三行小于10一下的数据,并且仅仅列出帐号与第三栏,# cat /etc/passwd | awk ' BEGIN {FS=":"} $3<10 {print &1 "\t" $3}'。一个查表统计的例子(P257)# cat pay.txt | awk 'NR==1{printf "%10s %10s %10s %10s %10s\n", $1,$2,$3,$4,"TOTAL"} NR>=2{total = $2+$3+$4 printf "%10s,%10d,%10d,%10d,%10.2f\n",$1,$2,$3,$4,total}'
~~~文件数据比较与显示~~~
-
diff: sed以后有两个操作的时候都要加上-e,diff [-bBi] b忽略一行中有多个空白的 B忽略空白行 i忽略大小写的,也可以比较目录,比较不同目录相同文件名子的不同。
-
cmp:用位比较,可以比较二进制文件,diff是行,它是位
-
patch:可以将旧文件升级为新文件,mkdir /tmp/old; cp/etc/passwd /tmp/old mkdir /tmp/new; cp/tmp/test/passwd /tmp/new cd /tmp;diff -Naur old/ new/ > test.patch cd /tmp/old patch -p1 < /tmp/test.patch p1为减掉一层目录。 patch.file即为补丁文件,私房菜中有详细介绍。
####################################################################################################################################################
###############################################################2012.08.13 BASH SHELL################################################################
在Linux里边,命令行方式其实是相当于bash的工具与接口,在linux中bash是默认的shell。
计算机要输出音乐的时候,计算机都要做些什么:
-
硬件的支持,硬件设备,否则不会有声音;
-
操作系统的核心支持这个芯片集,还要提供驱动程序;
-
用户要发出命令,告诉计算机要发声音,即输出的命令;
基本的输出步骤就是这样了,我们就是通过shell将输入的命令与核心沟通,让核心来控制硬件。
通常工作的是硬件,控制硬件的是核心,用户通过shell与核心进行沟通。
kernel是最内层的核心,核心是操作系统最底层的东西,shell在最外头。
当登陆的时候,系统会给我们一个shell让我们工作,登陆取得的shell记录在/etc/passwd里边,每一行的最后一个数据,就是系统提供给的shell。
Bash Shell 的功能
-
命令记忆功能:能够记住使用过的命令在~/.bash_history中
-
命令与文件补全功能
-
命令别名设置功能(alias),eg: # alias lm="ls -al"
-
作业控制,前台,后台控制????????????
-
通配符,加快操作进度
Bash Shell 的内置命令:用type命令观察即可。
=====> # type [-tpa] name 其中,type -p touch 类似的能查看命令路径,功能类似于which。
执行命令 #command [-option] parameter1 parameter2 ...
说明:有时候完整参数的名称会输入--符号,例如--help,命令太长的时候使用\符号来转义回车键,不过\后面要立即接特殊字符。
当我们顺利的在终端(tty)上登录以后,Linux就会根据/etc/passwd的文件设置,给我们一个shell,默认就是bash。
Shell的变量功能(变量就是以一组文字或者符号,来替换一些设置或者是一串保留的数据)
为了简化整个运行流程,我们通过某个变量的功能,让这个变量可以根据不同用户而更改内容,当然可以更改这些变量,但如果变量直接于套件中,那么,当修改某些参数之后,套件就必须要重新编译,所以变量真的很方便。
使用:在大型的脚本当中使用变量,比如一些目录,修改所有就麻烦了,所以用变量就改动一处,在正确登录之后,系统需要一些变量提供数据访问,或者设置一些参数值,现实色彩等,所以就要读入一些“环境变量”,这些环境变量如PATH HOME MAIL SHELL等等,区别一般变量,这些大写。、
变量的获取与设置:echo, unset
设置规则:
-
变量设置的时候,等号左右边不能直接连空格符;
-
若有空格符。可以使用双引号或者单引号将变量内容结合起来,但是注意,双引号内的特殊字符可以保持变量特性,但单引号内的特殊字符仅为单一字符。就是双引号内的特殊字符可以不用管,单引号内的必须加上转义符。(enter 空格 $ / ' 等);
-
在一串命令之中,还需要通过其他命令提供的信息,可以使用这样的方式“·command·” 不是单引号,是数字键1边上的;
-
如果该变量要在其他子程序中执行,需要用export编程环境变量;
-
取消变量的方法:unset
=====> 在PATH目录中累加目录:两种方法------1,# PATH=$PATH:/home/shishang/bin
2,# PATH="$PATH":/home/shishang/bin
=====> 这个例子不可以:将name内容多出一个yes------# name=$nameyes 错误
------# name="$name"yes正确
------# name=${name}yes正确
=====> 刚刚设置的变量在下一个shell程序中用?一般情况下,子进程内无法使用父进程定义的变量,都是用export变成.
=====> 如何进入到当前核心的模块目录?# cd /lib/modules/`uname -r`/kernel 其中``中的取得内核版本。
双引号和单引号的区别最大在于,双引号仍然可以保持变量的内容,但是单引号只能是一般字符,而不会有特殊符号。
=====> # name=Vbird #echo $name #myname="$name its me" #echo $myname #myname='$name its me' #echo $myname 单引号的话$name失去了原有的意义,打印不是想要的。
变量的用途
-
简化路径名称;
-
另一个需要变量的情况是在脚本里,存储路径的设置
当然如果是与系统中断环境相关的设置,很多时候也是利用变量帮助实现的,即‘环境变量’
#############################################################2012.8.16###############################################################################
环境变量的功能
环境变量可以帮助我们实现许多功能,包括家目录的修改,提示符的显示,执行文件的搜索路径等等。
我们使用的shell环境中有多少变量呢,可以用两个命令来查看:env , export
=====>一些环境变量的说明:# env
命令会显示许多环境变量:其中比较关键的几个是
-
HOME 用户的家目录
-
SHELL 告诉我们这个环境是用的shell是哪个程序,如果是bash 默认为 /bin/bash。
-
ENV 这是用户的个性化环境设置文件的读取文件
-
PATH 执行文件的搜索路径,是有顺序的。/root/.bashrc
-
LANG 这个很重要,就是语系文件
-
RANDOM 这个是随机数变量,当前大多数版本都有随机数发生器。就是/dev/random文件
=====> declare -i number=$RANDOM*10/32767 ; echo $number 打印0到9 的随机数
=====> 其他所有变量的声明 #set
在bash环境下,还有一些重要的变量,这些变量时在‘shell环境下有效· 如果是在子程序中,变量的值就不同了,其他自定义的变量以及所有的变量使用set命令都会显示,使用大写字母设置的变量一般为系统内定需要的变量。
使用set 除了会将系统默认值显示出来,自己设置的也会显示出来,当有多个人在线的时候,自己的变量只能自己使用,除非改的是系统默认的参数文件 如/etc/profile 不会干扰到别人。如果想要变量没吃都出现在登陆的自动设置好,必须将设置好写入登录时加载的设置文件。
-
PS1: 提示符的设置,命令提示符的设置
-
$ 关于本shell的ID 表示当前这个进程的进程号,想要知道命令是:# echo $$
-
?上一个执行命令的回传代码。成功返回0
-
OSTYPE HOSTTYPE MACHTYPE 主机硬件与核心的等级,与程序安装有关,
======> [root@linux /home/shishang 16:50 #12]# 应该用这样来设置PS1 PS1='[\u@\h \W \A #\#]\$' 其中 \h 表示仅仅取主机的名称的第一个名字 \u表示当前用户的账号名称 \W 利用basename取得的共组目录名称,仅会列出最后一个目录名字 \A 显示时间 \#表示执行的第几个命令 \$提示符 如果是root则为 # 否则为$
自定义变量转换成环境变量:
=====> # export 变量
环境变量与自己定义的变量,主要是由变量是否可以被子程序调用区别的
父进程中定义的自己变量不会继续存在,只有环境变量存在于子程序中。 如果想要是自定义的变量继续在子程序之中运行使用就只想上边的命令。直接export所有环境变量都显示出来。
语系文件的变量(locale)
=====> # locale -a
中文语系支持两种以上的编码,热门的utf-8编码,通过LANG 等等相关的可以修改这编码,仅仅需设置LANG即可,语系文件都保存在/usr/lib/local目录中,
变量的有效范围
被export的环境变量存在于子程序中,其他自定义的变量不会存在子程序中,只在当前的shell环境中存在,除非使用export把自定义变量转换成环境变量。比如两个文件sh1.sh 和sh2.sh 如果后者回去引用前者的变量,这个时候在前者中必须export设置,否则变量将无法再两个版本之间互用,当这个脚本文件执行完毕之后,变量刚刚的设置无效了。
环境变量可以让子程序引用的原因:
-
启动一个shell的时候,操作系统分配一块内存个shell使用,这个区域的变量可以让子程序访问。
-
利用export功能,可以让变量写到上述内存中(环境变量)
-
当加载另外一个shell的时候(启动子程序,离开原来的程序),子程序可以讲父shell的环境变量导入自己的环境变量区域
变量的键盘读取数组与声明 read array declare
变量的设置也可以通过键盘, 我们可以声明这个变量的属性。例如数组或者数字。
======> #read [-pt] variable -p后边可以接提示符-t后面接等待的描述 用户通过键盘输入内容, #read atest 输入 this is test #echo $atest 显示this is test -p -t 同理 read -p "please...." -t 30 nbamed -p 使用后会美观一些。
======># declare [-aixr] variable -a定义为数组variable -i数字,-x将其变成环境变量 -r 设置成只读,不能修改也不能unset。
# sum=100+50
#echo $sum
100+50
#eclare -i sum=100+50
#echo $sum
150
数组在脚本中比较常用:
在bash中数组的设置方式为 var[index]=content 一个数组名字为var,
# var[1]="smallming"
# var[2]="bigming"
# echo "${var[1]}, ${var[2]}"
建议直接以${数组}方式读取,正确无误。
##########################################################2012.08.17#################################################################
与文件系统及程序的限制关系:
======>#ulimit [-SHacdflmnpstv] 配额
同时有10人登陆或更多的时候,内存要用的大了就要限制。bash 是可以限制用户的某些系统资源的,包括可以打开的文件数量,可以使用的cpu时间,可以使用的内存总量等,用ulimit设置,例如,#ulimit -a 列出所有的限制额度,#ulimit -f 1024, 限制文件大小。、
附加变量的设置功能:
假设变量名是vbird 设置为/home/vbird/testing/text.x.sh
=======> #echo ${vbird##/*/} #echo ${vbird#/*/} 前者打印出 完整路径,后者打印出/home/
=======> #echo ${vbird%%/*/} 完整路径 #echo ${vbird%/*}只删除text.x.sh
=======> #echo ${vbird/testing/TEST}字符串替换,如果是//则后边的都替换。
命令别名与历史命令:
命令别名设置:
=======> # alias rm='rm -i' #unalias rm 设置与取消设置
历史命令:
=======> #history [n] 列出n行 #history -c 全部清除 [-raw] histfile man查询下
Bash Shell 使用环境:
我们习惯环境变量,命令别名等等,是否可以再登录时就设置好呢,这些文件设置值又分为系统设置值和自己喜欢设置值,区别在于文件放置的地点不同。
绝对路径与相对路径注意!
登录消息显示书记: /etc/issue /etc/motd
当我们登录tty1-tty6时候开头有几个提示的字符串,就在文件/etc/issue中,
如果想让大家都知道的消息,可以将消息加入/etc/motd中。当登录后告诉登录者这里设置的消息。
环境设置文件:bashrc,~/.bashrc,~/.profile,profile... ,/etc/inputre,source
至于bash的环境,系统规划与个人喜好不同,一般来说,用户直接修改个人设置值即可,不需要改系统。在命令行输入的变量,命令别名,都针对该次登录的设置,一旦注销上次的值就不见了。我们需要几个文件,每次登录的时候,都帮助我们确定环境的设置。
-
系统设置值
-
每个用户进入到系统bashshell以后,都会读取设置文件,默认的有:/etc/sysconfig/i18n,一般用户不要修改,可以设置自己的设置文件。
-
/etc/profile 这里设置了几个重要的变量 如PATH USER MAIL HOSTNAME umask 等,可以在这里设置总体的PATH环境值,用户都适用这个文件的信息,所以设置要小心,一般讲PATH中的第一个值设置为~/bin 因为是我自己安装的套件最喜欢,所以最先搜索,此外,可以将HISTSIZE设置成50,比较安全,要特别注意此文件。
-
/etc/bashrc 这个文件确定umask的功能,同时确定提示符的内容(PS1那个)不同版本位置可能不一样
-
/etc/profile.d/*.sh 这个目录其实是在/etc/profile文件内确定的,可以自行设置一些具有*.sh的文件名的文件来书写自己的系统设置值
-
/etc/man.config 对于系统管理员很重要
上边就是系统在设置时候常用的文件,特别注意的是,设置完这几个文件之后,要先注销再登录,设置才生效。
2. 个人设置值 在个人家目录下面的几个隐藏文件中,会使用到以下几个文件
-
~/.bash_profile,~/.bash_login,~/.profile
-
~/.bashrc 笔者一般都是将自己需要输入到这个文件,我的个性化设置都在这个文件中,例如命令别名,设置等等,每次执行shell脚本的时候,都会重新读取这个文件,所以是最完整的,而~/.bash_profile 只有在登录时候才读取一次,
-
~/.bash_history 历史命令
-
~/.bash_logout 文件记录当我注销bash之后,系统帮我做完什么操作后才离开。可以将一些备份或者其他重要的事情写在这个文件中。
当我们登录shell的时候,我们的这些设置文件时这样读取的:
-
先读取/etc/profile 在根据它的内容读取其他附加的设置文件,例如/etc/inpurc等等
-
根据不同的用户,到家目录下读取~/.bash_profile或~/.bash_login或~/.profile等设置文件
-
根据不同的用户,到家目录下去读取~/.bashrc.
所以登录bash之后最后读取的是c中提到的文件,这里的会是最终的设置值,所以将自己喜欢的alias和PATH设置在这个文件中,不论系统帮我们设置什么值,我都可以使用属于自己喜欢的环境。
使用source file 来让设置文件立即生效。修改c中提到的文件 直接source立即进入自己设置的环境。当管理多个案例的时候,设置不同的环境变量设置文件,直接管理。
3. 登录shell和非登录shell
X环境下登录的都是非登录shell。在取得登录shell继续操作其他的非登录shell 读取的就仅仅有~/.bashrc。
#######################################################################2012.08.18####################################################################
终端环境设置:tty, set
在我们登录终端的时候,会自动取得一些终端输入环境的设置。在tty登录的时候,我们可以取得一些字符设置的功能。
=====> #stty -a 列出参数
通配符与特殊符号
-
? 代表一定有一个字符
-
$ 变量之前需要加的变量替换值
-
& 将变量变成后台工作
-
>> > 输出导向 分别是 累加 和 替换
-
‘’ 具有变量替换的功能 ‘不具有变量替换的功能
-
` ` 中间是可以先执行的命令、
-
( ) 中间为子shell的起始与结束
-
[ ] 中间为字符的组合
-
{ } 中间为命令区块的组合
-
ctrl+m 回车键
-
ctrl+u 提示符下删除命令
-
ctr+z pause the current command
=====> # test[1-5] /tmp copy test1-5 to /tmp
redirect(数据流的重新导向)
一串命令最左边的一定是命令 在 > 2> << 右边的一定是文件或者设备才行。
如果要输出正确的数据不要错误的信息,这个时候/dev/null垃圾桶就很重要的了,属于黑洞垃圾桶功能, 2> /dev/null 将错误信息丢掉
要将数据写到同一个文件,用下面的命令
=====> # find /home -name testing > list 2>$1
使用其他的文件代替键盘输入
=====> # cat > file < catfile
当我要用cat直接将输入的消息输出到catfile中,当输入eof结束
=====> # cat > catfile << eof
使用输出重导向的场合
-
当屏幕的输出信息很重要的时候,而且我们需要将他们存储下来的时候
-
后台执行的程序,不希望它干扰屏幕正常输出的结果
命令执行的判断根据
=====> #ls /tmp && touch shsnag 当前边的正确的时候才会进行第二个命令 || 是相反,当前边命令错误的时候才会执行后边的命令。
管道命令
选取命令 cut grep
=====> # cut -d '分割符' -f filelds or -c 字符范围 #echo $PATH | cut -d ':' -f 3,5 #export | -c 12- 取出12个以后的字符
cut 是处理一行消息中我们想要的部分,grep则是分析一行消息,若其中有需要的消息,就将该行取出。简单的语法如下:grep [-acinv] '搜索字符串' filename -c 是搜索字符串的次数 -a 是二进制文件以文本方式搜索,
======> #last | grep 'root'|cut -d ' ' -f1 取出root行 只要第一栏
排序命令 sort wc uniq
=====> sort [-fbMnrutk] file uniq [-ic] wc[-lwm] l显示多少行 w多少词 m 多少字符
双向重导向
=====> tee [-a] file a 以累加的方式加入file中 在数据流的处理过程之中某段消息存储下来
=====> # ls -l / | tee -a file | more
字符转换命令
-
tr [-ds] set1 ... 用来删除一段消息中的文字 或者进行文字消息的替换 -d 删除 -s 替换 # last | tr '[a-z]' '[A-Z]' #cat /etc/passwd | tr -d ':'
-
col [-x] x 将tab键转换成对等的路径 #cat -A /etc/man.config |col -x |cat -A|more 输出美观多了
-
join [-ti12] file2 file2 #join -t ':' /passwd1 /passwd2 /etc/passwd中的第四个字段是GID,GID记录在/etc/group的第三个字段 整合的话 # join -t ':' -1 4 /etc/passwd -2 3 /etc/passwd
-
paste [-d] file1 file2 直接将两行贴在一起,如果file1的部分 写成 - 则是标准输入的数据
-
expand 就是将tab键转换成空格键 expand [-t] file
-
split [-bl] b拆分文件的大小 l按行数进行拆分 /etc/termaap 由700多k 差分成300K一个文件,#split -b 300k /etc/termcap termcap
-
参数代换 xargs [-Oepn] #cut -d ':' -f 1 < /etc/passwd | head -n 3|xargs finger 用cut取出帐号名称, 取出3个帐号,作为 finger后面的三个参数 # cut -d ':' -f 1 < /etc/passwd | xargs -p -e'lp' finger 执行-e'lp'的时候 分析到后边的lp字符串时候后面的stdin的内容就会舍弃掉
减号(-)的用途
管道命令在bash连续的处理程序中相当重要。登录文件的分析中也相当重要。
#tar -cvf - /home | tar -xvf - 将home文件打包,打包的数据不记录到文件中,传送到stdout; 管道过后,传送给后面的命令,后边的-是取用前边命令的stdout。
环境变量文件的加载顺序是什么:先由/etc/passwd取得bash这个shell,再到/etc/profile中读取环境变数,同时将/etc/inputrc和/etc/profile.d内容均读入。最后到个人家目录下读取~/.bash_profile 和 ~/.bashrc
#################################################################学习SHELL脚本2012.08.19##############################################################
如果是it行业,想管理好自己的主机,必须学习shell脚本。可以进行类似程序的编写,并且不需要编译就可以执行,Linux中一些服务的启动都是shell脚本的。
什么是shel脚本 :程序使用纯文本文件,将一些shell语法与命令写在里边,与正则表达式,管道命令 和数据流重定向一起使用实现我们的目的。能够依次执行多个命令。SHELL脚本还提供了数组,循环,条件与逻辑判断等重要功能,用户也可以直接通过shell编写程序,不必使用类似C语言等传统程序编写的方法。不需要编译就可以执行,拥有不错的调试工具,可以帮助系统管理员快速管理主机。
为什么学习shell脚本?
-
自动化管理的重要依据,手动处理一些简单的程序每天自动管理处理分析
-
追踪与管理系统的重要工作,linux系统的服务启动的接口,在/etc/init.d目录下,所有文件都是脚本;包括引导过程也都是利用shell脚本来搜索系统的相关设置数据,然后再带入各个服务的设置参数
-
简单的入侵检测,系统异常时候,会记录在系统登录文件中,我们可以在固定的几分钟主动分析系统登录文件,如果有问题,就立刻解决。
-
连续命令单一化,防火墙连续规则(iptables)启动加载程序的项目都是相似的功能(/etc/rc.d/rc.local里的数据)
-
简单的数据处理
-
跨平台学习缩短学习历程
虽然shell脚本号称是程序,但是实际上,shell脚本处理速度不怎么快,由shell脚本用的是外部命令与bash shell的一些默认工具,所以常常调用外部函数库,速度比不上传统语言,shell 在系统管理上是很好的工具,但是用在处理大量数值运算上就不够了,还很麻烦。处理速度慢,占用cpu资源较多,造成主机资源分配不足。
脚本的编写与执行
#!/bin/bash 声明脚本使用的shell名称,声明文件内使用bash的语法,系统判断由哪个shell来执行
要说明该脚本的:内容与功能,版本信息,作者与联系方式,文件创建日期,历史记录等等
主要环境变量的声明,设置号PATH 让程序在进行时候,直接执行命令,而不必写绝对路径。
主要程序部分写好即可。
脚本内特殊的命令使用绝对路径来执行。
预先声明与设脚本运行需要的环境变量。
简单的脚本练习:
-
1 #!/bin/bash 2 3 #Program: 4 5 # Let user keyin their first and lasht name, and show their full name. 6 7 #History 8 9 #2012.08.19 shishang firstrelease 10 11 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 12 13 export PATH 14 15 16 17 read -p "please input your first name: " firstname 18 19 read -p "please input your last name : " lastname 20 21 echo -e "your full name is: $firstname $lastname"
变量内容由自己决定
-
要建立三个文件,起始文件由用户输入决定,假设用户输入filename,今天日期是2012/08/19,要按照前天,昨天,今天日期建立文件,即filenam_20120818 filename_20120819 filename_20120820
1 #!/bin/bash 2 3 #Program: 4 5 # user can keyin filename to touch 3 new file 6 7 #History 8 9 #2012.08.19 shishang firstrelease 10 11 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 12 13 export PATH 14 15 16 echo -e "I will use touch command to create 3 new files." 17 18 read -p "Please input your file name what you want: " fileuser 19 20 21 filename=${fileuser:-"filename"} #为了避免用户随意按enter键,使用变量功能分析是否设置了文件名。如果filename变量名位设定,或者为空,取-后边的 22 23 名字作为变量值,否则filenam=$fileuser 24 25 26 date1=`date --date='2 days ago' +%Y%m%d` 27 28 date2=`date --date='1 days ago' +%Y%m%d` 29 30 date3=`date +%Y%m%d` #注意+号前边的空格 31 32 33 file1="$filename""$date1" 34 35 file2="$filename""$date2" 36 37 file3="$filename""$date3" 38 39 40 touch $file1 41 42 touch $file2 43 44 touch $file3
-
#!/bin/bash #Program: # user can input 2 integer to cross by! #History #2012.08.19 shishang firstrelease PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "You should input 2 number, I will cross they! \n" read -p "first nuymber: " firstnu read -p "second number: " secnu total=$(($firstnu*$secnu)) echo -e "\nThe number $firstnu X $secnu is ===> $total"
数字运算可以运用“declare -i total=$firstnu*$secnu” 推荐使用var=$((运算内容))不仅容易记忆,也方便
-
善用判断条件 用test命令可以直接代替 ls 然后再 echo $? 判断存在与否,#test -e /dmtsai && echo"exist" || echo "not exist" 其他的标志如下: 某个文件名的类型的检测 -e 是否存在,-b 是否为一块设备,-c 是否为字符设备,-s 文件名是否为一个套接字文件,-p 是否为一个fifo管道文件 -L 文件名是否为一个连接文件。文件权限的检测 test -r filenam -r -w -x 读写执行 -u suid属性 -g sgid属性 -k Sticky bit 属性,-s 文件名是否为空白文件。比较两个文件,test file1 -nt file2 判断file1是否比file2新 -ot 旧,-ef 判断两个文件是否均指向同一个inode 是否为同一文件,用于判断硬链接。多重条件的判断 test -r filename -a -x filename -a 两个条件同时成立,filename 同时具有r与x 权限时候,才回传true。 -o 有一个就成立,! test ! -x file file不具有x时 回传true.
1 #!/bin/bash 2 #Program: 3 # Let user input a filename, the program will search the filename 4 # 1)exist? 2) file/directory? 3)file permissions 5 #History 6 #2012.08.19 shishang firstrelease 7 8 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 9 10 export PATH 11 12 13 echo -e "The program will show you that filename is exist which input by you.\n" 14 15 read -p "Input a filename : " filename 16 17 test -z $filename && echo "You must inpout a filename" && exit 0 18 19 20 test ! -e $filename && echo "The filename $filename do not exist" && exit 0 21 22 23 test -f $filename && filetype="regulare file" 24 25 test -d $filename && filetype="directory" 26 27 test -r $filename && perm="readable" 28 29 test -w $filename && perm="$perm writeable" 30 31 32 echo -e "The filename: $filename is a $filetype" 33 34 echo -e "And the permission are: $perm"
使用判断符号[ ] 使用 # [ -z $HOME ] 判断是否为空 注意的是:1,括号内每个要用空格分开,内的变量最好用双引号来设置[ "$HOME" == "MAIL" ] 括号内的常量最好用但因号或双引号设置,常常用在if then fi情况中 shell脚本的默认变量($0.$1)当shell脚本执行的时候,已经做好了一些可用的变量,比如说要启动一个系统服务的时候,可能会执行: # /etc/init.d/crond restart 因为shell脚本已经设置好了,一些指定的变量,是这样的,前边的那个 命令是$0 restart是$1 依次排序。
echo "The scripst name is :" $0
[ -n "$1" ] && echo "The 1st parameter is ===> $1" || exit 0
[ -n "$2" ] && echo "The 2st parameter is ===> $2" || exit 0
上边的例子都是用的bash 的相关功能,接下来使用条件判断设置单独功能!!!
#######################################################2012.08.20条件判断 循环#########################################################################
条件判断
if [ 条件判断表达式 ]; then
当条件判断表达式成立时,可以执行的命令
fi
多个中括号可以隔开用&& ||
if [ 条件判断表达式 ]; then
当条件判断表达式成立时, 可以执行的命令
else
当条件判断表达式不成立的时候,可以执行的命令
fi
if [ 条件判断表达式一 ]; then
当条件判断表达式一成立的时候,可以执行的命令
elif [条件判断表达式二 ]; then
当判断表达式二成立的时候,可以执行的命令
else
均不成立的时候,可以执行的命令
fi
-
-
#!/bin/bash #Program: # The program will show user's choice #History #2012.08.20 shishang firstrelease PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Input (Y/N) : " yn if [ "$yn" == "hello" ]; then echo "Hello, how are you" elif [ "$yn" == "" ]; then echo "You must input parameters, ex> $0 someword" else echo "The only parameter is 'hello'" fi
-
# netstat -tuln 获取当前主机启动的服务 常见的有: 80:www 22:ssh 21:ftp 25:mail 四个主要的服务端口