bash shell 基础

来源:互联网 发布:淘宝拍机器注意事项 编辑:程序博客网 时间:2024/05/29 03:17

输入输出

关于输入、输出和错误输出

在字符终端环境中,标准输入/标准输出的概念很好理解。输入即指对一个应用程序或命令的输入,无论是从键盘输入还是从别的文件输入;输出即指应用程序或命令产生的一些信息;与 Windows 系统下不同的是,linux 系统下还有一个标准错误输出的概念,这个概念主要是为程序调试和系统维护目的而设置的,错误输出与标准输出分开,可以让一些高级的错误信息不干扰正常的输出信息,从而方便一般用户的使用。

在 linux 系统中:标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕(上面的 std 表示 standard)。在 BASH 中使用这些概念时一般将标准输出表示为 1,将标准错误输出表示为 2。下面我们举例来说明如何使用他们,特别是标准输出和标准错误输出。

输入、输出及标准错误输出主要用于 I/O 的重定向,就是说需要改变他们的默认设置。先看这个例子:

$ ls > ls_result
$ ls -l >> ls_result

上面这两个命令分别将 ls 命令的结果输出重定向到 ls_result 文件中和追加到 ls_result 文件中,而不是输出到屏幕上。">"就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个 ">" 符号,即 ">>" 则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子:

$ find /home -name lost* 2> err_result

这个命令在 ">" 符号之前多了一个 "2","2>" 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在 err_result 文件中。大家可以设想一下 find /home -name lost* 2>>err_result 命令会产生什么结果?

如果直接执行 find /home -name lost* > all_result ,其结果是只有标准输出被存入 all_result 文件中,要想让标准错误输出和标准输入一样都被存入到文件中,那该怎么办呢?看下面这个例子:

$ find /home -name lost* > all_result 2>& 1

上面这个例子中将首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 all_result 这个文件中。这样我们就可以将所有的输出都存储到文件中了。为实现上述功能,还有一种简便的写法如下:

$ find /home -name lost* >& all_result

如果那些出错信息并不重要,下面这个命令可以让你避开众多无用出错信息的干扰:

$ find /home -name lost* 2> /dev/null

同学们回去后还可以再试验一下如下几种重定向方式,看看会出什么结果,为什么?

$ find /home -name lost* > all_result 1>& 2
$ find /home -name lost* 2> all_result 1>& 2
$ find /home -name lost* 2>& 1 > all_result

另外一个非常有用的重定向操作符是 "-",请看下面这个例子:

$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)

该命令表示把 /source/directory 目录下的所有文件通过压缩和解压,快速的全部移动到 /dest/directory 目录下去,这个命令在 /source/directory 和 /dest/directory 不处在同一个文件系统下时将显示出特别的优势。

下面还几种不常见的用法:

n<&- 表示将 n 号输入关闭
        <&- 表示关闭标准输入(键盘)
        n>&- 表示将 n 号输出关闭
        >&- 表示将标准输出关闭

         

流程控制

        BASH 中的基本流程控制语法

BASH 中几乎含有 C 语言中常用的所有控制结构,如条件分支、循环等,下面逐一介绍。

if...then...else

if 语句用于判断和分支,其语法规则和 C 语言的 if 非常相似。其几种基本结构为:

if [ expression ]
then
  statments
fi

或者

if [ expression ]
then
  statments
else
  statments
fi

或者

if [ expression ]
then
  statments
else if [ expression ]
  then
    statments
  else
    statments
fi

或者

if [ expression ]
then
  statments
elif [ expression ]
  then
    statments
  else
    statments
fi

值得说明的是如果你将 if 和 then 简洁的写在一行里面,就必须在 then 前面加上分号,如:if [ expression ]; then 下面这个例子说明了如何使用 if 条件判断语句:

#!/bin/bash

if [ $1 -gt 90 ]
then
  echo "Good, $1"
elif [ $1 -gt 70 ]
  then
    echo "OK, $1"
  else
    echo "Bad, $1"
fi

exit 0

上面例子中的 $1 是指命令行的第一个参数,这个会在后面的“BASH 中的特殊保留字”中讲解。

                 

for

for 循环结构与 C 语言中有所不同,在 BASH 中 for 循环的基本结构是:

for $var in [list]
do
  statments
done

其中 $var 是循环控制变量,[list] 是 $var 需要遍历的一个集合,do/done 对包含了循环体,相当于 C 语言中的一对大括号。另外如果do 和 for 被写在同一行,必须在 do 前面加上 ";"。如: for $var in [list]; do 。下面是一个运用 for 进行循环的例子:

#!/bin/bash

for day in Sun Mon Tue Wed Thu Fri Sat
do
  echo $day
done

# 如果列表被包含在一对双引号中,则被认为是一个元素:

for day in "Sun Mon Tue Wed Thu Fri Sat"
do
  echo $day
done

exit 0

注意上面的例子中,在 for 所在那行的变量 day 是没有加 "$" 符号的,而在循环体内,echo 所在行变量 $day 是必须加上 "$" 符号的。另外如果写成 for day 而没有后面的 in [list] 部分,则 day 将取遍命令行的所有参数。如这个程序:

#!/bin/bash

for param
do
  echo $param
done

exit 0

上面这个程序将列出所有命令行参数。for 循环结构的循环体被包含在 do/done 对中,这也是后面的 while、until 循环所具有的特点。

                

while

while 循环的基本结构是:

while [ condition ]
do
  statments
done

        这个结构请大家自己编写一个例子来验证。

        

until

until 循环的基本结构是:

until [ condition is TRUE ]
do
  statments
done

这个结构也请大家自己编写一个例子来验证。

        

case

BASH 中的 case 结构与 C 语言中的 switch 语句的功能比较类似,可以用于进行多项分支控制。其基本结构是:

case "$var" in
 condition1 )
  statments1;;
 condition2 )
  statments2;;
 ...
 * )
  default statments;;
esac

下面这个程序是运用 case 结构进行分支执行的例子:

#!/bin/bash

echo "Hit a key, then hit return."
read Keypress

case "$Keypress" in
 [a-z] ) echo "Lowercase letter";;
 [A-Z] ) echo "Uppercase letter";;
 [0-9] ) echo "Digit";;
 * ) echo "Punctuation, whitespace, or other";;
esac

exit 0

上面例子中的第四行 "read Keypress" 一句中的 read 语句表示从键盘上读取输入。这个命令将在本讲义的 BASH 的其他高级问题中讲解。

       

break/continue

        熟悉 C 语言编程的都很熟悉 break 语句和 continue 语句。BASH 中同样有这两条语句,而且作用和用法也和 C 语言中相同,break 语句可以让程序流程从当前循环体中完全跳出,而 continue 语句可以跳过当次循环的剩余部分并直接进入下一次循环。

       

函数

函数的使用

BASH 是一个相对简单的脚本语言,不过为了方便结构化的设计,BASH 中也提供了函数定义的功能。BASH 中的函数定义很简单,只要向下面这样写就可以了:

function my_funcname {
 code block
}

或者

my_funcname() {
 code block
}

上面的第二种写法更接近于 C 语言中的写法。BASH 中要求函数的定义必须在函数使用之前,这是和 C 语言用头文件说明函数方法的不同。

更进一步的问题是如何给函数传递参数和获得返回值。BASH 中函数参数的定义并不需要在函数定义处就制定,而只需要在函数被调用时用 BASH 的保留变量 $1 $2 ... 来引用就可以了;BASH 的返回值可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的返回一个返回值,则返回值就是该函数最后一条语句执行的结果(一般为 0,如果执行失败返回错误码)。函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。下面我们就来看一个用函数来计算整数平方的例子:

#!/bin/bash

square() {
 let "res = $1 * $1"
 return $res
}

square $1
result=$?
echo $result

exit 0

0 0
原创粉丝点击