新建一个文本文件包含所需要的脚本。举例,我会使用pico编辑器写一个脚本用来运行程序tar,带上必要的可选项可以用来解压从因特网下载下来的*.tar的文件(我好像总是记不住tar的所有参赛)。我决定把我的脚本名称叫做“untar”:
pico untar
因为在我的当前工作目录里untar文件不存在,所有pico文本编辑器自动创建这个文件,现在,我输入以下内容:
#!/bin/bash
echo this is the script file $0
echo untarring the file $1
# this calls tar with options -xvzf (extract,
# verbose, filter through gzip, input filename)
tar -xvzf $1
我使用
脚 本的第一行,以“#!”开始是特别的提示-它告诉shell应该用哪一个程序来解释我的脚本。在这个例子里,我使用bash shell /bin/bash。第一行必须使用“#!”开头,否则脚本不会运行(系统认为是一个文本文件)。其他以“#”开始的行是注释行只是给作者和读者使用的, 计算机将跳过这些行。
在以上脚本里,参数$0, $1, $2…是传递到脚本里面的参数。举个例子,如果我运行我的脚本名“myscript”带七个参数如下:
myscript a b c d e f g
那么,参赛$0就是myscript, $1就是a, $2就是b,$3就是c,依此类推。
脚本的第二行和第三行,echo命令输出所有在它后面同一行上的文本,然后扩展在脚本里对应的参数$0和$1。第四行和第五行是我写的注释文本,提醒我在这个脚本里要做的事情。只有最后一行是真正起作用的。
一旦脚本已经写好,我把文件属性改成对文件拥有者是“可执行”的:
chmod u+x untar
然后我的脚本就可以这样运行了:
./untar my_tar.tar.gz
Liunx脚本的确非常丰富,灵活,功能强劲,还可能有点复杂。然而,对于日常任务编写一些简单脚本,它并不需要什么特别高深的知识。你可以把一些要用到的命令放在一起,一个接一个,输入到文件里。我使用脚本很频繁是因为我太懒了,不想一次一次的输入相同的命令。
一个最简单的方法,可以把一组命令放在文本文件里然后使用source命令传递给shell让它直接运行:
source my_file
这个时候就不需要在文本第一行加上“#!”的标志了。
3.4.6 引号的含义
一般来说,以下字符对于shell有特殊的含义:
\ ' " ` < > [ ] ? | ; # $ ^ & * ( ) =
这里有四种不同的符号:反斜杠(\),单引号(‘),双引号(“),反向单引号(`)。
反斜杠(\)表示:关闭后面字符的特殊含义
单引号(‘)表示:关闭在两个单引号之间所有字符的特殊含义
双引号(“)表示:关闭在两个双引号之间所有字符的特殊含义除了$ ` \
反向单引号(`)表示:告诉shell首先运行两个反向单引号之间的命令,然后把得到的结果再传递给两个单引号之外的命令。同样的功能也可以通过“$command”命令来实现,而且可能会更方便。
举个例子,我可以创建一个奇怪的目录名叫做“*”通过使用“\”或者“’”符号:
mkdir \*
mkdir ’*’
这屏蔽了“*”对于shell的特别含义。如果没有“\”,“*”意味着当前目录下所有文件。
3.4.7 输入输出重定向
有三个最重要的输入输出流:标准输入(stdin),标准输出(stdout),标准错误(stderr)。它们对于控制台(“控制台”指的是键盘用于输入,屏幕用于输出)来说是缺省的,但是它们可以被重定向。
重定向标准输出,可以使用“>”符号,举例:
dir my_dir > filelisting.txt
将把dir命令的标准屏幕输出重定向到文本文件 filelisting.txt文件里,所以屏幕上没有任何输出。这个文件可以用来编辑(比如使用pico文本编辑器)或者合并到其他的文件里。
重定向标准错误,可以使用结构“2>”,举例:
dir my_dir 2> errorlisting.txt
以上命令将送标准输出到屏幕上,如果没有错误信息,将没有任何信息写到errorlisting.txt文件里。如果出错,则没有什么东西输出到屏幕,而文件errorlisting.txt将包含错误信息。错误信息有可能是这样的:
dir: my_dir: Permission denied
最后,我也可以把标准输出和标准错误一起输出到同一个文件里,
dir my_dir > file_and_error_listing.txt 2>&1
以上命令先重定向标准输出到文本文件里,然后再重定向标准错误到和标准输出同样的位置。它如何实现可能看起来有点古怪,但是是可行的。
在以上的例子里,如果重定向的文件已经存在,该文件会被覆盖。如果你要追加到该文件的末尾,可以使用“>>”符号,以上的例子就变成:
dir my_dir >> filelisting.txt
dir my_dir 2>> errorlisting.txt
dir my_dir >> file_and_error_listing.txt 2 > &1
如果你对“2>”感到很迷惑,这里有一个简单的办法可以帮你理解,标准流有标准的解析器:“0”代表标准输入,“1”代表标准输出,“2”代表标准错误。
dir my_dir > file.txt
是以下命令的简写方式:
dir my_dir 1 > file.txt
那么以下命令就是用来输出标准错误:
dir my_dir 2 > file.txt
还有,你还可以使用符号“|”(管道命令)把一个命令的标准输出送到另外一个命令的标准输入。在以下这个标准的例子里,dir命令的标准输出通过管道输入到命令more里(输出满屏的时候自动暂停):
dir | more
你还可以使用“tee”命令把标准输出同时写到文件和屏幕,
dir | tee filelisting.txt
tee是“T型连接器”的模拟音,在管道中的主要的用途是分流。
这个部分这样都用来讲述标准输出重定向,对于标准输入重定向不像标准输出重定向那么有用,但是它可以使用以下方式实现:
cat <>
还有一种叫做“直接插入式”的标准输出,可以通过“<<”来实现。不要管它了,看起来对我没有什么实际用处。不过,如果你真的想知道,这里有一个例子(这里“>”式第二个提示符)
cat <<>
> my_line_from_the_keyboard
> another_line_from_the_keyboard
> my_marker
除了重定向到常规文件和“过滤器”之外(如以上的例子所示),你还可以重定向到设备和其他特殊文件。看下面这些例子。
重定向到设备文件的例子。以下命令将显示文件列表到第四个文本终端:
dir > /dev/tty4
以下是一个重定向到一个特殊的FIFO(先进先出)文件的例子。该命令送信息”you are lucky”到叫做“lucky”的ICQ用户UIN 7777777 (假定你已经用你的ICQ程序连接到ICQF服务器上了)
echo message 7777777 “you are lucky” < ~/.licq/licq_fifo
以上的例子能够工作是因为在你licq目录下的文件“licq_fifo”是一个特别的FIFO序列文件。以上这个例子,对比于在图形用户界面下的ICQ程序有什么特别有用的地方吗?举个例子,你可以写一个短的脚本带上多个信息给你的那些ICQ伙伴们:
#!/bin/bash
echo Messaging UIN: $1 Message: $2 Times: $3
# The next command puts puts your licq in the status "on-line, invisible".
echo 'status *online' > ~/.licq/licq_fifo
c=0
while [ $c -le $3]
do
echo message $1 $2 > ~/.licq/licq_fifo
c=`expr $c + 1`
echo $c " "
done
echo 'status offline' > ~/.licq/licq_fifo
echo "all done"
这个例子利用了licq通信模型(FIFO文件)和简单的文件重定向功能,给你一个关于如何 “自动化”licq的主意。
3.4.8 Shell的特殊字符(metacharacters)
一般来说,这些字符对于shell有特别的含义:
\ ' " ` < > | ;
以下是这些字符的含义:
\ ‘ “ 和 ‘ 主要用来注释,前面已经描述过 (参见 3.4.6)。
< 和 > 主要用来输入和输出重定向
| 是管道命令,管道左边的标准输出是管道右边的标准输入
; 用于间隔在同一命令行上的几个命令
( ) 用于封装需要使用不同的shell启动的命令, 比如 ( dir )
{ } 用于封装要用当前shell启动的一组命令,比如 { dir },需要空格间隔
& 使当前命令在后台运行(有它自己独立的进程),所以下一条命令不需要等待前一条命令结束才能开始。
* 当搜索文件时,它匹配除了以“.”开头的所有文件
?当搜索文件时,它匹配任何单个字符
[ ] 当搜索文件时,它匹配任何在[]里面的单个字符
&& 是用于连接两个命令的“与操作”,
command1 && command2, 只有当command1退出状态为0时(没有错误),command2才会被执行。比如, cat file1 && cat file2 只有当file1正常显示时, file2才能被显示。
|| 是用于连接两个命令的“或操作”
command1 || command2, 只有当command1退出状态非0时(有错误),command2才会被显示。比如:cat file1 || cat file2 只有当显示file1出错时,file2才能被显示
= 指定值给变量
举例,命令me=blahblah设定值“blahblah”给变量“me”,我可以输出变量名:
echo $me
$ 预处理扩展变量名
变量可以使用“=”来设定值,也可以通过预先变量设定来设置
$0 被执行的shell脚本的名称
$# 按位置对应的命令输入参数, $1第一个参赛, $2第二个参数, $3第三个参数…直到$9
$* 扩展所有的位置参数给命令
$@ 扩展所有的位置参数给命令,但是当“$@”使用时,参数个别标注
Pasted from <http://www.blogjava.net/pdw2009/archive/2006/09/16/70061.html>
No comments:
Post a Comment