Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145354
  • 博文数量: 24
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 291
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-01 09:36
文章分类

全部博文(24)

文章存档

2010年(4)

2009年(13)

2008年(7)

我的朋友

分类:

2009-01-16 17:40:05

http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/index.html
定义变量时单引号'和双引号"是不同的:
$ a='test!'
$ b="test!"
bash: !": event not found
是因为单引号禁用了称为扩展的bash特性, 其中, 特殊字符和字符系列由值替换. 例如!字符是历史扩展字符, bash通常将其替换为前面输入的命令.
$ echo $a
test!
$ echo foo$abar    % bash无法识别要引用哪个变量($a/$ab/$aba/$abar)
foo
$ echo foo${a}bar
footest!bar

导出变量:
$ export XXX=value
取消导出:
$ unset XXX

截断字符串获取文件名:
$ basename /a/b/c/d.txt
d.txt
获取目录名:
$ dirname /a/b/c/d.txt
/a/b/c

命令替换:
$ MYDIR = `dirname /a/b/c/d.txt`
$ echo $MYDIR
/a/b/c
或者:
$ MYDIR = $(dirname /a/b/c/d.txt)

进阶:
$ MYVAR=foodfordinner.jpg
$ echo ${MYVAR##*fo}    % 从字符串开始处查找匹配"*fo"的最长子字符串,将其从字符串的开始出截去
rdinner.jpg
$ echo ${MYVAR#*fo}     % 匹配最短的子字符串并截去
odfordinner.jpg
$ VAR=foobar.tar.gz     % 从字符串末尾开始查找
$ echo ${VAR%%.*}
foobar
$ echo ${VAR%.*}
foobar.tar

分段截取:
$ echo ${VAR:0:3}
foo
$ echo ${VAR:8:555}
ar.gz

测试命令行指定文件是否是tar文件:
-----------------------------------
#!/bin/bash
if [ "${1##*.}" = "tar" ]      # bash中所有布尔表达式都用方括号括起
then
    echo This appears to be a tarball.
else
    echo At first glance, this does not appear to be a tarball.
fi
-----------------------------------
$1 指传递给脚本的第一个参数
$# 指传递给脚本的参数的个数
$@ 指用空格分开的所有参数

if语法:
if [ condition1 ]
then
    action1
elif [ condition2 ]
then
    action2
.
.
.
elif [ conditionn ]
then
    actionn
else
    actionx
fi

便利语法:
if [ -z "$myvar" ]
then
    echo "myvar is not defined"
fi

-e filename     如果 filename存在,则为真     [ -e /var/log/syslog ]
-d filename     如果 filename为目录,则为真     [ -d /tmp/mydir ]
-f filename     如果 filename为常规文件,则为真     [ -f /usr/bin/grep ]
-L filename     如果 filename为符号链接,则为真     [ -L /usr/bin/grep ]
-r filename     如果 filename可读,则为真     [ -r /var/log/syslog ]
-w filename     如果 filename可写,则为真     [ -w /var/mytmp.txt ]
-x filename     如果 filename可执行,则为真     [ -L /usr/bin/grep ]
filename1 -nt filename2     如果 filename1比 filename2新,则为真     [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2     如果 filename1比 filename2旧,则为真     [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string     如果 string长度为零,则为真     [ -z "$myvar" ]
-n string     如果 string长度非零,则为真     [ -n "$myvar" ]
string1 = string2     如果 string1与 string2相同,则为真     [ "$myvar" = "one two three" ]
string1 != string2     如果 string1与 string2不同,则为真     [ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq num2     等于    [ 3 -eq $mynum ]
num1 -ne num2     不等于    [ 3 -ne $mynum ]
num1 -lt num2     小于    [ 3 -lt $mynum ]
num1 -le num2     小于或等于    [ 3 -le $mynum ]
num1 -gt num2     大于    [ 3 -gt $mynum ]
num1 -ge num2     大于或等于    [ 3 -ge $mynum ]


字符串比较说明:
大多数时候,虽然可以不使用括起字符串和字符串变量的双引号,但这并不是好主意。为什么呢?因为如果环境变量中恰巧有一个空格或制表键,bash 将无法分辨,从而无法正常工作。这里有一个错误的比较示例:

if [ $myvar = "foo bar oni" ]
then
     echo "yes"
fi


在上例中,如果 myvar 等于 "foo",则代码将按预想工作,不进行打印。但是,如果 myvar 等于 "foo bar oni",则代码将因以下错误失败:

 [: too many arguments


在这种情况下,"$myvar"(等于 "foo bar oni")中的空格迷惑了 bash。bash 扩展 "$myvar" 之后,代码如下:

 [ foo bar oni = "foo bar oni" ]


因为环境变量没放在双引号中,所以 bash 认为方括号中的自变量过多。可以用双引号将字符串自变量括起来消除该问题。请记住,如果养成将所有字符串自变量用双引号括起的习惯,将除去很多类似的编程错误。"foo bar oni" 比较 应该写成:

 if [ "$myvar" = "foo bar oni" ]
then
     echo "yes"
fi

以上代码将按预想工作,而不会有任何令人不快的意外出现.


for循环语法:
for x in ../* mystuff/*
do
    echo $x is a silly file
done

shell算术:
$ echo $(( 100 / 3 ))
33
$ myvar="56"
$ echo $(( $myvar + 12 ))
68
$ echo $(( $myvar - $myvar ))
0
$ myvar=$(( $myvar + 1 ))
$ echo $myvar
57

while与until:
myvar=0
while [ $myvar -ne 10 ]
do
    echo $myvar
    myvar=$(( $myvar + 1 ))
done

可以看到,上例使用了算术表达式来使条件最终为假,并导致循环终止。

"Until" 语句提供了与 "while" 语句相反的功能:只要特定条件为 假 ,它们就重复。下面是一个与前面的 "while" 循环具有同等功能的 "until" 循环:

myvar=0
until [ $myvar -eq 10 ]
do
    echo $myvar
    myvar=$(( $myvar + 1 ))
done

case语法:
case "${x##*.}" in
     gz)
           gzunpack ${SROOT}/${x}
           ;;
     bz2)
           bz2unpack ${SROOT}/${x}
           ;;
     *)
           echo "Archive format not recognized."
           exit
           ;;
esac

自定义函数:
tarview() {
     echo -n "Displaying contents of $1 "
     if [ ${1##*.} = tar ]
then
         echo "(uncompressed tar)"
         tar tvf $1
     elif [ ${1##*.} = gz ]
then
         echo "(gzip-compressed tar)"
         tar tzvf $1
     elif [ ${1##*.} = bz2 ]
then
         echo "(bzip2-compressed tar)"
         cat $1 | bzip2 -d | tar tvf -
fi
 }
将以上代码加入~/.bashrc或者~./bash_profile中,
$ . .bashrc
$ tarview foo.tar.gz


在 bash 中,每当在函数内部创建环境变量,就将其添加到全局名称空间。这意味着,该变量将重写函数之外的全局变量,并在函数退出之后继续存在
解决方法是在局部变量声明前加上local关键字.

Gentoo Linux ebuild实现(bash):
http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-3/index.html



目录的读权限意味着可以列出其中的内容
目录的写权限意味着可以在该目录中创建文件
目录的执行权限意味着可以搜索和访问该目录


chmod -R -h owner file
- R选项意味着对所有子目录下的文件也都进行同样的操作。- h选项意味着在改变符号链
接文件的属主时不影响该链接所指向的目标文件。

不管是否在同一个文件系统中,都可以创建链接。链接一旦创建,链接目录将具有权限7 7 7,但是实际的原
有文件的权限并未改变。

软链接和硬链接的区别:
4点不同 :
(1)软连接可以 跨文件系统 ,硬连接不可以 。
(2)关于 I节点的问题 。硬连接不管有多少个,都指向的是同一个I节点,会把 结点连接数增加,只要结点的连接数不是 0,文件就一直存在 ,不管你删除的是源文件还是 连接的文件 。只要有一个存在 ,文件就 存在 (其实也不分什么源文件连接文件的 ,因为他们指向都是同一个 I节点)。 当你修改源文件或者连接文件任何一个的时候 ,其他的 文件都会做同步的修改。软链接不直接使用i节点号作为文件指针,而是使用文件路径名作为指针。所以 删除连接文件 对源文件无影响,但是 删除源文件,连接文件就会找不到要指向的文件 。软链接有自己的inode,并在磁盘上有一小片空间存放路径名.
(3)软连接可以对一个不存在的文件名进行连接 。
(4)软连接可以对目录进行连接。

备注:I节点 :它是UNIX内部用于描述文件特性的数据结构.我们通常称I节点为文件索引结点(信息结点).i节点 含有关于文件的大部分的重要信息,包括文件数据块在磁盘上的地址.每一个I节点有它自己的标志号,我们称为文件顺序号.I节点包含的信息 1.文件类型 2.文件属主关系 3.文件的访问权限 4.文件的时间截.


希望在系统根目录下查找更改时间在5日以内的文件,可以用:
$ find / -mtime -5 -print
为了在/ v a r / a d m目录下查找更改时间在3日以前的文件,可以用:
$ find /var/adm -mtime +3 -print

$ find . -type f -exec ls -l {} \;
$ find . -name "*.log" -mtime +5 -ok rm {} \;

在使用f i n d命令的- e x e c选项处理匹配到的文件时, f i n d命令将所有匹配到的文件一起传递
给e x e c执行。不幸的是,有些系统对能够传递给e x e c的命令长度有限制,这样在f i n d命令运行
几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是
x a rg s命令的用处所在,特别是与f i n d命令一起使用。F i n d命令把匹配到的文件传递给x a rg s命
令,而x a rg s命令每次只获取一部分文件而不是全部,不像- e x e c选项那样。这样它可以先处理
最先获取的一部分文件,然后是下一批,并如此继续下去.
$ find / -type f -print | xargs grep "device"

f i n d命令是一个非常优秀的工具,它可以按照用户指定的准则来匹配文件。使用e x e c和
x a rg s可以使用户对所匹配到的文件执行几乎所有的命令。


crontab:
下面是crontab的格式:
分< >时< >日< >月< >星期< >要运行的命令
其中< >表示空格。
crontab文件的一个条目是从左边读起的,第一列是分,最后一列是要运行的命令,它位
于星期的后面。
在这些域中,可以用横杠-来表示一个时间范围,例如你希望星期一至星期五运行某个作
业,那么可以在星期域使用1 - 5来表示。还可以在这些域中使用逗号“,”,例如你希望星期一
和星期四运行某个作业,只需要使用1 , 4来表示。可以用星号*来表示连续的时间段。如果你
对某个表示时间的域没有特别的限定,也应该在该域填入*。该文件的每一个条目必须含有5
个时间域,而且每个域之间要用空格分隔。该文件中所有的注释行要在行首用#来表示。
crontab运行脚本时,要由用户来给出脚本的绝对路径,设置相应的环境变量

$ crontab -l       % 列出crontab文件的内容
$ crontab -e       % 修改
$ crontab -r       % 删除


at命令的基本形式为:
at [-f script] [-m -l -r] [time] [date]
其中,
-f script 是所要提交的脚本或命令。
-l 列出当前所有等待运行的作业。atq命令具有相同的作用。
-r 清除作业。为了清除某个作业,还要提供相应的作业标识(ID);有些Unix变体只接受atrm作为清除命令。
-m 作业完成后给用户发邮件。
time at命令的时间格式非常灵活;可以是H、HH. HHMM、HH:MM或H:M,其中H和M分别是小时和分钟。还可以使用a.m.或p.m.
date 日期格式可以是月份数或日期数,而且a t命令还能够识别诸如today、tomorrow这样
的词。
$ at 20:10
at> find /etc/ -name "menu.lst" -print
at> Ctrl-D

at还可识别如下格式的时间日期:
at 6.45am May12
at 11.10pm
at now + 1hour
at 9am tomorrow
at 15:00 May 24
at now + 10 minutes

提交脚本:
$ at 3.00pm tomorrow -f /path/to/script.sh
列出提交的作业:
$ at -l           % or atq
删除:
$ atrm job #      % #通过at -l命令查看

命令放到后台执行并重定向屏幕输出到文件:
$ command > out.file 2>&1 &
用户退出登陆后进程不退出:
$ nohup command &

$ echo -e "string \c\t\n..."
$ read val
tee: 把输出的一个副本送到stdout, 另一个副本拷贝到相应的文件中
$ who | tea who.out
$ cat who.out


表5-1 常用文件重定向命令
command > filename 把把标准输出重定向到一个新文件中
command >> filename 把把标准输出重定向到一个文件中(追加)
command 1 > fielname 把把标准输出重定向到一个文件中
command > filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中
command 2 > filename 把把标准错误重定向到一个文件中
command 2 >> filename 把把标准输出重定向到一个文件中(追加)
command >> filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中(追加)
command < filename >filename2 把c o m m a n d命令以f i l e n a m e文件作为标准输入,以f i l e n a m e 2文件
作为标准输出
command < filename 把c o m m a n d命令以f i l e n a m e文件作为标准输入
command << delimiter 把从标准输入中读入,直至遇到d e l i m i t e r分界符
command <&m 把把文件描述符m作为标准输入
command >&m 把把标准输出重定向到文件描述符m中
command <&- 把关闭标准输入

顺序执行命令(前一个命令成功返回才执行下一个):
$ command1 && command2 && ...
n选1执行命令:
$ command1 || command2 || ...


正则表达式之grep:
在grep命令中输入字符串参数时,最好将其用双引号括起来。例如:“mystring”。这样做
有两个原因,一是以防被误解为shell命令,二是可以用来查找多个单词组成的字符串,例如:
“jet plane”,如果不用双引号将其括起来,那么单词plane将被误认为是一个文件,查询结果
将返回“文件不存在”的错误信息。
在调用变量时,也应该使用双引号,诸如: grep "$MYVAR"文件名,如果不这样,将没有返回结果。
在调用模式匹配时,应使用单引号。

常用的g r e p选项有:
-c 只输出匹配行的计数。
-i 不区分大小写(只适用于单字符)。
-h 查询多文件时不显示文件名。
-l 查询多文件时只输出包含匹配字符的文件名。
-n 显示匹配行及行号。
-s 不显示不存在或无匹配文本的错误信息。
-v 显示不包含匹配文本的所有行。

$ grep -E '216|219' data.log        % 匹配216或219  [-E允许grep使用扩展模式匹配]

类等价的正则表达式类等价的正则表达
[[:upper:]] [A-Z]      
[[:alnum:]] [0-9a-zA-Z]
[[:lower:]] [a-z]      
[[:space:]] 空格或tab键
[[:digit:]] [0-9]
[[:alpha:]] [a-zA-Z]

阅读(827) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-02-26 12:59:54

看的是ibm文档写的笔记吧