Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1122040
  • 博文数量: 165
  • 博客积分: 5957
  • 博客等级: 大校
  • 技术积分: 2015
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-24 15:04
文章分类

全部博文(165)

文章存档

2014年(10)

2013年(14)

2012年(9)

2011年(22)

2010年(17)

2009年(17)

2008年(26)

2007年(34)

2006年(16)

我的朋友

分类: LINUX

2008-07-24 15:55:26

1. 变量说明

$$ 
Shell本身的PID(ProcessID) 
$! 
Shell最后运行的后台Process的PID 
$? 
最后运行的命令的结束代码(返回值) 
$- 
使用Set命令设定的Flag一览 
$* 
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
$@ 
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 
$# 
添加到Shell的参数个数 
$0 
Shell本身的文件名 
$1~$n 
添加到Shell的各参数值。$1是第1参数、$2是第2参数…。 

2、I/O重定向

    shell进程默认会有三个文件描述符(fd,即file descriptors)"STDIN","STDOUT","STDERR".它们对应的索引值就是STDIN_FILENO(0),STDOUT_FILENO(1),STDERR_FILENO(2).这些符号名定义在unistd.h中
    注意:使用fd 5可能会引起问题. 当Bash使用exec创建一个子进程的时候, 子进程会继承fd 5。
    当xterm运行的时候, 它首先会初始化自身. 在运行用户shell之前, xterm会打开终端设备(/dev/pts/ 或者类似的东西)三次. Bash继承了这三个文件描述符, 而且每个运行在Bash上的命令(子进程)也都依次继承了它们, 除非你重定向了这些命令.意味着将这些文件描述符中的某一个, 重新分配到其他文件中(或者分配到一个管道中, 或者是其他任何可能的东西). 文件描述符既可以被局部重分配(对于一个命令, 命令组, 一个子shell, 一个while、if或case结构,也可以全局重分配
 

/* Standard file descriptors. */
#define    STDIN_FILENO    0    /* Standard input. */
#define    STDOUT_FILENO    1    /* Standard output. */
#define    STDERR_FILENO    2    /* Standard error output. */

 

M>filename
  # "M"是一个文件描述符, 如果没有明确指定的话默认为1.
1>filename
  # 重定向stdout到文件"filename".
1>>filename
  # 重定向并追加stdout到文件"filename".
2>filename
  # 重定向stderr到文件"filename".
2>>filename
  # 重定向并追加stderr到文件"filename".
&>filename
  # 将stdout和stderr都重定向到文件"filename".

M>&N
  # "M"是一个文件描述符, 如果没有明确指定的话默认为1. 
  # 重定向文件描述符M到文件描述符N,指向M文件的所有输出都发送到N.
2>&1
  # 重定向stderr到stdout.将错误消息的输出, 发送到与标准输出所指向的地方.
>&j
  # 默认的, 重定向文件描述符1(stdout)到j.
  # 所有传递到stdout的输出都送到j中去.

0 < FILENAME或者<FILENAME
  # 都表示从文件中接受输入.

[j]<>filename
   # 为了读写"filename", 把文件"filename"打开, 并且将文件描述符"j"分配给它. 
   # 如果文件"filename"不存在, 那么就创建它. 
   # 如果文件描述符"j"没指定, 那默认是fd 0, stdin.
   # 这种应用通常是为了写到一个文件中指定的地方.
示例:(注意以下exec执行时描述符3后面要紧跟操作符,切切注意)
   echo 1234567890 > File # 写字符串到"File". 
   exec 3<> File # 打开"File"并且将fd 3分配给它. 
   read -n 4 <&3 # 只读取4个字符.
   echo -n . >&3 # 写一个小数点.
   exec 3>&- # 关闭fd 3.
   cat File # ==> 1234.67890

 

关闭文件描述符:

n<&-    #关闭文件描述符n

0<&-, <&-   #关闭stdin

n>&-   #关闭输出文件描述符n

1>&-, >&-   #关闭stdout

 

什么时候使用关闭文件描述符,比如:

子进程默认继承了打开的文件描述符。这就是为什么管道可以工作。但我们也可以阻止fd被继承,那么这时可以关掉它

   exec 3>&1  # 保存当前stdout的"值".

   ls -l 2>&1 >&3 3>&- | grep bad 3>&-    #对grep关闭fd 3,但不关闭ls

   exec 3>&-  # 对于剩余的脚本来说, 关闭它.

2、判断环境变量是否被设置

: ${HOSTNAME?} ${USER?} ${MAIL?}
# 如果一个或多个必要的环境变量没被设置的话, 就打印错误信息.

# :是占位符
: ${HOSTNAME?"hostname is not set"} ${USER?} ${MAIL?}

3、反转操作

[root@nagios4 ~]# true
[root@nagios4 ~]# echo $?
0
[root@nagios4 ~]# ! true     #反转
[root@nagios4 ~]# echo $?
1
[root@nagios4 ~]# !true     #启用bash的历史机制
true
[root@nagios4 ~]# !ls     #启用bash的历史机制
ls -al 2>&1 >&3

需要注意的是,在一个脚本中,历史机制是被禁用的.

4、“保留的”退出码

退出码的值对应的含义:

1--通用错误(如let "a=1/0")

2--shell内建命令使用错误(Bash文档上有说明)

126--程序或命令的权限是不可执行的

127--"command not found"

128--exit参数错误(如exit 3.14)

128+n--信号"n"的致命错误,如kill -9 $PPID,如果$?返回137,即128+9

130--用Control-C来结束脚本,Control-C是信号2的致命错误, (130 = 128 + 2)

255*--超出范围的退出状态,如exit -1。注意超出范围的退出值可能会产生意想不到的退出码. 如果退出值比255大, 那么退出码将会取256的模. 举个例子, exit 3809的退出码将是225(3809 % 256 = 225).

阅读(1699) | 评论(0) | 转发(0) |
0

上一篇:tcpdump

下一篇:你的名字刻在我的心上

给主人留下些什么吧!~~