Bash


---------------------------------------------------------------------------

                                   关于重定向

文件描述符  名字        通用缩写    典型默认
0           标准输入    stdin       键盘
1           标准输出    stdout      屏幕
2           标准错误    stderr      屏幕

    大部分的 UNIX 程序都有两种输出,第一种叫做标准输出(standard output),另一种是标准错误输出(standard error)。标准错误输出是一个叫做 stderr 的文件句柄,也就是打印错误信息的地方,通常是屏幕。
    使用>将不会重定向标准错误输出。如果你想重定向标准错误输出的话,在 > 符号前面(或者后面)加一个 & (两者之间不要加空格);如果你只想重定向标准错误输出而不想重定向标准输出,在 > 符号前面加一个 2 (shell 很专制地把1指定给标准输出,而把 2 指定给标准错误输出;专业一点的说法是:标准输出的文件句柄是 1,标准错误输出的文件句柄是 2)。
    如果你想要抛弃输出,使它不出现在屏幕上,解决的方法是把它重定向到一个叫做 /dev/null 的特殊文件中。/dev 目录是 UNIX 系统用以存放指向终端、磁带机和其他设备的特殊文件之处,但是 /dev/null 是独特的,这是一个把你送入的数据全部投入黑洞的地方。举例来说,下列命令会储存标准错误输出,但是会遗弃标准输出:
    $ gcc test.c 2> error-msg > /dev/null

                                   重定向格式

> file
    将标准输出重定向到文件 file,输出结果将覆盖文件原有内容
< file
    将标准输入重定向到文件 file
n> file
    将文件描述符中 n 的输出重定向到文件 file,输出结果将覆盖文件原有内容 (n 和 > 之间不能有空格)
    (n 为 2 时是标准错误)
n< file
    设置文件 file 为文件描述符 n (n 和 < 之间不能有空格)
>> file
    将标准输出重定向到文件 file,若 file 已存在则把输出结果追加到原有内容的末尾
cmd1 | cmd2
    管道:将 cmd1 的标准输出作为 cmd2 的标准输入
>| file
    即使已设置 noclobber,也强行将标准输出重定向到文件 file
n >| file
    即使已设置 noclobber,也强行将文件描述符 n 中的输入重定向到文件 file
<> file
    将标准输入和标准输出都重定向到文件 file
&> n
    将标准输出和标准错误都重定向到文件 file
<< identifier
    读标准输入直到内容为 identifier 的行 (text 可以存放在 shell 变量中)。输入
    通常被键入在屏幕上或者 shell 程序中。如果 text 被引号引起来,则标准输入将
    不进行变量转换、命令置换等
<< /identifier (/ 和 identifier 之间不能有空格)
    在 << identifier 格式中,shell 会对随后输入的内容进行参数替换,命令替换并
    识别反斜杠字符。如果希望 shell 原样保留随后输入的内容,即不希望 shell 的
    上述动作,我们可以使用 << /identifier 格式
<<- identifier (<< 和 - 之间不能有空格)
    基本同 << identifier 格式,唯一的区别在于 shell 会去掉随后输入的内容中每
    行开头的所有制表符。这样结束标志也与 << identifier 格式不同了,应该是仅含
    identifier 或仅含制表符和 identifier 的行 (有制表符的话所有的制表符都必须
    出现在identifier的前面,否则不能被识别为结束标识)
>& n
    将标准输出重定向到文件描述符 n
<& n
    将标准输入重定向到文件描述符 n
>& -
    关闭标准输出
        # ls >&-
        ls: 写入时发生错误: 错误的文件描述符
        #
<& -
    关闭标准输入
        # cat <&-
        cat: -: 错误的文件描述符
        cat: closing standard input: 错误的文件描述符
        #
n >& -
    关闭文件描述符 n 的输出
n <& -
    关闭文件描述符 n 的输入

注:其中文件描述符可以是 0, 1, 2 (分别代表标准输入,标准输出,标准错误),也可以是文件名。例如,将标准输出和标准错误集中到同一个文件 (下面三个命令均可):
    &> file
    > file 2>> file (2 和 >> 之间不能有空格)
    > file 2>& 1 (2 和 > 之间不能有空格)
但第三个命令换成
    2>& 1 > file
则不行,因为这样就先把标准错误重定向到标准输出 (默认为终端) 了,然后才把标准输出重定向到 file。

                          动态重定向标准输入和标准输出

    执行 exec < file 命令之后所有需要从标准输入读取数据的命令和程序都将从文件 file 读取输入。要想恢复标准输入为终端,执行 exec < /dev/tty 即可。标准输出和标准错误的情况相同。

---------------------------------------------------------------------------

两种命令替换格式的区别

关于 `command` 格式和 $(command) 格式对反斜杠 / 处理的不同:

`command` 格式中,“/”被 shell 处理为转义字符 (如果后跟特殊含义字符 $, /, ` 的话) ,因此 `echo /$x` 的结果相当于直接在命令行中输入 echo $x 并回车得到的结果,于是执行 echo `echo /$x` 得到结果为变量 x 的值。

而 $(command) 格式中,“/”被 shell 处理为普通字符,因此 $(echo /$x) 的结果相当于直接在命令行中输入 echo /$x 并回车得到的结果,于是执行 echo $(echo /$x) 得到结果为 $x。

可以将命令替换理解为将要替换的命令传递给一个子 shell 执行,然后将得到的结果返回到被替换命令的位置继续执行父 shell 里的命令。`echo /$x` 中,被传递给子 shell 的实际是 echo $x;而 $(echo /$x) 中被传递给子 shell 的就是 echo /$x。


参考:http://www.chinaunix.net/jh/24/686286.html

---------------------------------------------------------------------------

关于子 shell

内嵌子 shell (当前 shell 中 (command) 产生的子 shell) 和脚本中的子 shell 的区别:
1. 内嵌子 shell 除了可以继承当前 shell 的环境变量,还可以继承其他变量,但是用脚本中的子 shell 不会
2. (echo $$) 回显的是当前 shell 而不是内嵌子 shell 的进程号

---------------------------------------------------------------------------

特殊 shell 变量

$#  命令行键入的参数个数

$*  命令行键入的所有参数

"$@"
    命令行键入的所有参数,与 $* 的不同在于:
    shell 将 $* 替换成 $1 $2 $3...,而将 "$@" 替换成 "$1" "$2" "$3"...

${n}
    命令行键入的第 n 个参数,n 小于 10 时花括号可省略

$?  最后执行命令的退出状态,0 为成功,非 0 为失败

$$  当前进程的进程号

$0  所执行 shell 程序的程序名
    例如:
    # cat showname
    echo $0
    # chmod u+x showname
    # ./showname
    ./showname
    #

$!  最后送到后台的进程的进程号

$-  显示所有已设置的 shell 选项

!$  最后一条命令的最后一个参数,或者最后一条命令 (如果最后一条命令没有参数)

---------------------------------------------------------------------------

去掉 bash 中按 tab 键补全时的 beep 声

在 bash 中按 tab 键补全时,如果有两个以上的匹配,就会有 beep 声。如果觉得这个 beep 声烦人,可以去掉它,方法如下:
在用户主目录下的 .inputrc (没有的话就新建一个) 中加入如下语句:
set bell-style none

---------------------------------------------------------------------------

bash 内嵌命令 getopts 示例及说明

例子来自《Advanced Bash−Scripting Guide》。

其中行
    while getopts ":mnopq:rs" Option
中第二个冒号的作用是说明选项 q 应该带参数,
第一个冒号是可选的,其作用是屏蔽系统自带的错误消息。

#!/bin/bash
# Exercising getopts and OPTIND
# Script modified 10/09/03 at the suggestion of Bill Gradwohl.


# Here we observe how 'getopts' processes command line arguments to script.
# The arguments are parsed as "options" (flags) and associated arguments.

# Try invoking this script with
# 'scriptname -mn'
# 'scriptname -oq qOption' (qOption can be some arbitrary string.)
# 'scriptname -qXXX -r'
#
# 'scriptname -qr' - Unexpected result, takes "r" as the argument to option "q"
# 'scriptname -q -r' - Unexpected result, same as above
# 'scriptname -mnop -mnop' - Unexpected result
# (OPTIND is unreliable at stating where an option came from).
#
# If an option expects an argument ("flag:"), then it will grab
#+ whatever is next on the command line.

NO_ARGS=0
E_OPTERROR=65

if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
    echo "Usage: `basename $0` options (-mnopqrs)"
    exit $E_OPTERROR # Exit and explain usage, if no argument(s) given.
fi
# Usage: scriptname -options
# Note: dash (-) necessary


while getopts ":mnopq:rs" Option
do
    case $Option in
        m     ) echo "Scenario #1: option -m- [OPTIND=${OPTIND}]";;
        n | o ) echo "Scenario #2: option -$Option- [OPTIND=${OPTIND}]";;
        p     ) echo "Scenario #3: option -p- [OPTIND=${OPTIND}]";;
        q     ) echo "Scenario #4: option -q-/
    with argument /"$OPTARG/" [OPTIND=${OPTIND}]";;
        # Note that option 'q' must have an associated argument,
        #+ otherwise it falls through to the default.
        r | s ) echo "Scenario #5: option -$Option-";;
        *     ) echo "Unimplemented option chosen.";; # DEFAULT
    esac
done

shift $(($OPTIND - 1))
# Decrements the argument pointer so it points to next argument.
# $1 now references the first non option item supplied on the command line
#+ if one exists.

exit 0

# As Bill Gradwohl states,
# "The getopts mechanism allows one to specify: scriptname -mnop -mnop
#+ but there is no reliable way to differentiate what came from where
#+ by using OPTIND."

---------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值