📄 13.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0066)http://qref.sourceforge.net/Debian/reference/ch-program.zh-cn.html -->
<HTML><HEAD><TITLE>Debian 参考手册 - 编程</TITLE>
<META http-equiv=content-type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.3790.118" name=GENERATOR></HEAD>
<BODY><A name=ch-program></A>
<HR>
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-vcs.zh-cn.html">上一页</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/reference.zh-cn.html#contents">目录</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-preface.zh-cn.html">1</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-system.zh-cn.html">2</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-install.zh-cn.html">3</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-tutorial.zh-cn.html">4</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-woody.zh-cn.html">5</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-package.zh-cn.html">6</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-kernel.zh-cn.html">7</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-tips.zh-cn.html">8</A> ] [
<A href="http://qref.sourceforge.net/Debian/reference/ch-tune.zh-cn.html">9</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-gateway.zh-cn.html">10</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-edit.zh-cn.html">11</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-vcs.zh-cn.html">12</A> ] [
13 ] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-gnupg.zh-cn.html">14</A> ]
[ <A
href="http://qref.sourceforge.net/Debian/reference/ch-support.zh-cn.html">15</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ap-appendix.zh-cn.html">A</A>
] [ <A
href="http://qref.sourceforge.net/Debian/reference/ch-gnupg.zh-cn.html">下一页</A>
]
<HR>
<H1>Debian 参考手册 <BR>第 13 章 - 编程 </H1>
<HR>
<P>不要用“test”命名可执行的测试文件。<CODE>test</CODE>是一个shell的内建命令。
<HR>
<A name=s13.1></A>
<H2>13.1 从哪儿开始</H2>
<P>参考资源:
<UL>
<LI><CODE>/usr/share/doc/<VAR>package</VAR></CODE>下的文档和样例
<LI><CODE><A href="http://arioch.unomaha.edu/~jclark/#info">Unix / Programming
Information</A></CODE>
<LI><EM>Linux Programming Bible</EM> (John Goerzen/IDG books) </LI></UL>
<P>更详细的文档可以从<CODE><A href="http://www.gnu.org/">GNU</A></CODE>获得打印版本。
<P>接下来的四个小节中包含了用不同的编程语言编写的脚本样例,该脚本创建一个包含用户帐户信息的文本文件,调用一组进程如newusers程序,将这些信息加入到<CODE>/etc/passwd</CODE>。每个脚本均需要一个输入文件,该文件应包含格式如<SAMP>first_name
last_name password</SAMP>的行。(这些脚本并不创建真正的用户目录。)
<HR>
<A name=s-shell></A>
<H2>13.2 Shell</H2>
<P>理解类Unix系统如何工作的<STRONG>最好</STRONG>方法就是阅读shell脚本。在此,我们就shell编程做个简单的介绍。
<HR>
<A name=s-bash></A>
<H3>13.2.1 Bash – <STRONG>GNU</STRONG>标准交互式shell</H3>
<P>Bash参考资源:
<UL>
<LI><CODE>bash(1)</CODE>
<LI><SAMP>info bash</SAMP>
<LI>the LDP <CODE><A
href="http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html">BASH Programming -
Introduction HOWTO</A></CODE> as starter information.
<LI><SAMP>mc /usr/share/doc/bash/examples/ /usr/share/doc/bash/</SAMP>
<P>(安装<CODE>bash-doc</CODE>软件包阅读样例文件。) </P>
<LI><EM>Learning the bash Shell</EM>, 2nd edition (O'Reilly) </LI></UL>
<P>一个简短的程序样例(从标准输入端创建帐户信息供<CODE>newusers</CODE>使用): <PRE> #!/bin/bash
# (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain
pid=1000;
while read n1 n2 n3 ; do
if [ ${n1:0:1} != "#" ]; then
let pid=$pid+1
echo ${n1}_${n2}:password:${pid}:${pid}:,,,/home/${n1}_${n2}:/bin/bash
fi
done
</PRE>
<HR>
<A name=s-posix-shell></A>
<H3>13.2.2 POSIX shells</H3>
<P>Debian中有几个软件包提供了POSIX shell:
<UL>
<LI><CODE>dash</CODE> (Sarge)
<UL>
<LI>Priority: optional
<LI>Installed-Size: 176
<LI>Smallest and much fastest — best for initial boot </LI></UL>
<LI><CODE>ash</CODE> (Woody)
<UL>
<LI>Priority: optional
<LI>Installed-Size: 180
<LI>Smaller and much faster — good for initial boot </LI></UL>
<LI><CODE>bash</CODE>
<UL>
<LI>Essential: yes
<LI>Priority: required
<LI>Installed-Size: 580
<LI>Larger and featureful — many extensions implemented </LI></UL>
<LI><CODE>pdksh</CODE>
<UL>
<LI>Priority: optional
<LI>Installed-Size: 408
<LI>Complete AT&T ksh look-alike </LI></UL></LI></UL>
<P>如果你想编写具有通用性的shell脚本,最好写POSIX
shell脚本。可将<CODE>/bin/sh</CODE>链接到<CODE>ash</CODE>或(<CODE>dash</CODE>)来测试脚本的POSIX兼容性。避免用<STRONG>bash化</STRONG>或<STRONG>zsh化</STRONG>(它看起来与csh语法很相似)的思维去编写脚本。例如,应避免:
<UL>
<LI><SAMP>if [ <VAR>foo</VAR> == <VAR>bar</VAR> ] ; then ...</SAMP>
<LI><SAMP>diff -u <VAR>file</VAR>.c{.orig,}</SAMP>
<LI><SAMP>mkdir <VAR>/foo</VAR>{<VAR>bar</VAR>,<VAR>baz</VAR>}</SAMP> </LI></UL>
<HR>
<A name=s-shell-param></A>
<H3>13.2.3 Shell参数</H3>
<P>Several <STRONG>special parameters</STRONG> to remember: <PRE> $0 = shell名称或shel脚本名称
$1 = 第一个(1)shell参数
...
$9 = 第九个(9)shell参数
$# = 位置参数的个数
"$*" = "$1 $2 $3 $4 ... $<VAR>n</VAR>"
"$@" = "$1" "$2" "$3" "$4" ... "$<VAR>n</VAR>"
$? = 最近执行的命令的退出状态
$$ = 当前shell脚本的PID
$! = 最近启动的后台作业的PID
</PRE>
<P>需要记住的基本<STRONG>扩展参数</STRONG>: <PRE> Form If <VAR>var</VAR> is set If <VAR>var</VAR> is not set
${<VAR>var</VAR>:-<VAR>string</VAR>} $<VAR>var</VAR> <VAR>string</VAR>
${<VAR>var</VAR>:+<VAR>string</VAR>} <VAR>string</VAR> null
${<VAR>var</VAR>:=<VAR>string</VAR>} $<VAR>var</VAR> <VAR>string</VAR>
(并且执行<VAR>var</VAR>=<VAR>string</VAR>)
${<VAR>var</VAR>:?<VAR>string</VAR>} $<VAR>var</VAR> (返回<VAR>string</VAR>然后退出)
</PRE>
<P>在此,冒号“:”在所有运算表达式中事实上均是可选的。
<UL>
<LI>有“:” = 运算表达式测试“存在”和“非空”。
<LI>没有“:” = 运算表达式仅测试“存在”。 </LI></UL>
<P>需要记住的<STRONG>替换参数</STRONG>: <PRE> Form Result
${<VAR>var</VAR>%<VAR>suffix</VAR>} 删除位于var结尾的<VAR>suffix</VAR>最小匹配模式
${<VAR>var</VAR>%%<VAR>suffix</VAR>} 删除位于var结尾的<VAR>suffix</VAR>最大匹配模式
${<VAR>var</VAR>#<VAR>prefix</VAR>} 删除位于var开头的<VAR>prefix</VAR>最小匹配模式
${<VAR>var</VAR>##<VAR>prefix</VAR>} 删除位于var开头的<VAR>prefix</VAR>最大匹配模式
</PRE>
<HR>
<A name=s-shell-redirect></A>
<H3>13.2.4 Shell重定向</H3>
<P>需要记住的基本<STRONG>重定向</STRONG>(redirection)运算符(在此[<VAR>n</VAR>]表示可选参数): <PRE> [<VAR>n</VAR>]> <VAR>file</VAR> 重定向标准输出(或 <VAR>n</VAR>)到<VAR>file</VAR>。
[<VAR>n</VAR>]>> <VAR>file</VAR> 重定向标准输出(或 <VAR>n</VAR>)到<VAR>file</VAR>。
[<VAR>n</VAR>]< <VAR>file</VAR> 将<VAR>file</VAR>重定向到标准输入(或 <VAR>n</VAR>)。
[<VAR>n1</VAR>]>&<VAR>n2</VAR> 重定向标准输出(或 <VAR>n1</VAR>)到<VAR>n2</VAR>。
> <VAR>file</VAR> >&2 重定向标准输出和错误输出到<VAR>file</VAR>。
| <VAR>command</VAR> 将标准输出通过管道传递给<VAR>command</VAR>。
>&2 | <VAR>command</VAR> 将标准输出或错误输出通过管道传递给<VAR>command</VAR>。
</PRE>
<HR>
<A name=s-shell-cond></A>
<H3>13.2.5 Shell条件表达式</H3>
<P>每条命令均可返回一个<STRONG>退出状态</STRONG>,这个状态值可用于条件表达式:
<UL>
<LI>成功:0 (True)
<LI>错误:1–255 (False) </LI></UL>
<P>注意该用法,返回值0用来表示“true”与计算机其它领域中常见的转换是不同的。另外`['等阶于使用<CODE>test</CODE>命令进行参数赋值`]'相当于一个条件表达式。
<P>需要记住的常用基本<STRONG>条件表达式</STRONG>: <PRE> <VAR>command</VAR> && <VAR>if_success_run_this_command_too</VAR>
<VAR>command</VAR> || <VAR>if_not_success_run_this_command_too</VAR>
if [ <VAR>conditional_expression</VAR> ]; then
<VAR>if_success_run_this_command</VAR>
else
<VAR>if_not_success_run_this_command</VAR>
fi
</PRE>
<P>在条件表达式中使用的<STRONG>文件</STRONG>比较运算符有: <PRE> -e <VAR>file</VAR> <VAR>file</VAR>存在则返回True。
-d <VAR>file</VAR> <VAR>file</VAR>存在且是一个目录则返回True。
-f <VAR>file</VAR> 如果<VAR>file</VAR>存在且是一个普通文件则返回True。
-w <VAR>file</VAR> 如果<VAR>file</VAR>存在且可写则返回True。
-x <VAR>file</VAR> 如果<VAR>file</VAR>存在且可执行则返回True。
<VAR>file1</VAR> -nt <VAR>file2</VAR> 如果<VAR>file1</VAR>比<VAR>file2</VAR>新则返回True。(指修改日期)
<VAR>file1</VAR> -ot <VAR>file2</VAR> 如果<VAR>file1</VAR>比<VAR>file2</VAR>旧则返回True。(指修改日期)
<VAR>file1</VAR> -ef <VAR>file2</VAR> 如果两者是相同的设备和具有相同的结点(inode)数则返回True。
</PRE>
<P>条件表达式中使用的<STRONG>字符串</STRONG>比较运算符有: <PRE> -z <VAR>str</VAR> 如果<VAR>str</VAR>长度为零则返回True。
-n <VAR>str</VAR> 如果<VAR>str</VAR>长度为非零则返回True。
<VAR>str1</VAR> == <VAR>str2</VAR> 如果字符串相等则返回True。
<VAR>str1</VAR> = <VAR>str2</VAR> 如果字符串相等则返回True。
(使用"=="代替"="符合严格意义上的POSIX兼容)
<VAR>str1</VAR> != <VAR>str2</VAR> 如果字符串不相等则返回True。
<VAR>str1</VAR> < <VAR>str2</VAR> 如果<VAR>str1</VAR>排在<VAR>str2</VAR>之前则返回True(与当前位置有关)。
<VAR>str1</VAR> > <VAR>str2</VAR> 如果<VAR>str1</VAR>排在<VAR>str2</VAR>之后则返回True(与当前位置有关)。
</PRE>
<P>条件表达式中的<STRONG>算术</STRONG>整数比较运算符有<SAMP>-eq</SAMP>、<SAMP>-ne</SAMP>、<SAMP>-lt</SAMP>、<SAMP>-le</SAMP>、<SAMP>-gt</SAMP>和<SAMP>-ge</SAMP>。
<HR>
<A name=s-clprocess></A>
<H3>13.2.6 命令行处理</H3>
<P>shell按如下的方式处理脚本:
<UL>
<LI>用这些字符将其分割成<STRONG>tokens</STRONG>:SPACE, TAB, NEWLINE, ;, (, ), <,
>, |, &
<LI>如果不在"..."或'...'内就检查<STRONG>keyword</STRONG>(循环检查)
<LI>如果不在"..."或'...'内就扩展<STRONG>alias</STRONG>(循环检查)
<LI>如果不在"..."或'...'内就扩展<STRONG>brace</STRONG>,<SAMP>a{1,2}</SAMP> ->
<SAMP>a1 a2</SAMP>
<LI>如果不在"..."或'...'内就扩展<STRONG>tilde</STRONG>, ~<VAR>user</VAR> ->
<VAR>user</VAR>'s home directory
<LI>如果不在'...'内就扩展<STRONG>parameter</STRONG>, $<VAR>PARAMETER</VAR>
<LI>如果不在'...'内就扩展<STRONG>command substitution</STRONG>, $(<VAR>command</VAR>)
<LI>如果不在"..."或'...'内就用$IFS分割成<STRONG>words</STRONG>
<LI>如果不在"..."或'...'内就扩展<STRONG>pathname</STRONG> *?[]
<LI>查找<STRONG>command</STRONG>
<UL>
<LI>function
<LI>built-in
<LI>file in $PATH </LI></UL>
<LI>循环 </LI></UL>
<P>在双单号内单引号将失效。
<HR>
<A name=s13.3></A>
<H2>13.3 Awk</H2>
<P>Awk的参考资源:
<UL>
<LI><EM>Effective awk Programming</EM>, 3rd edition (O'Reilly)
<LI><EM>Sed & awk</EM>, 2nd edition (O'Reilly)
<LI><CODE>mawk(1)</CODE> and <CODE>gawk(1)</CODE>
<LI><SAMP>info gawk</SAMP> </LI></UL>
<P>简短的程序样例(创建<CODE>newusers</CODE>命令输入): <PRE> #!/usr/bin/awk -f
# Script to create a file suitable for use in the 'newusers' command,
# from a file consisting of user IDs and passwords in the form:
# first_name last_name password
# Copyright (c) KMSelf Sat Aug 25 20:47:38 PDT 2001
# Distributed under GNU GPL v 2, or at your option, any later version.
# This program is distributed WITHOUT ANY WARRANTY.
BEGIN {
# Assign starting UID, GID
if ( ARGC > 2 ) {
startuid = ARGV[1]
delete ARGV[1]
}
else {
printf( "Usage: newusers startUID file\n" \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -