高级 Bash 脚本编程指南
本教程内容转载自:https://github.com/LinuxStory/Advanced-Bash-Scripting-Guide-in-Chinese
感谢开源翻译!!!
本教程内容转载自:https://github.com/LinuxStory/Advanced-Bash-Scripting-Guide-in-Chinese
感谢开源翻译!!!
掌握 Linux 命令是编写有效的 shell 脚本必不可少的序曲。
本章节涉及了下列的命令:
.(参照 source)acadduseragettyagrepararchatautoloadawk(参考 使用 awk 进行数学运算)badblocksbannerbasenamebatchbcbgbindbisonbuiltinbzgrepbzip2calcallercatcdchattrchfnchgrpchkconfigchmodchownchrootcksumclearclockcmpcolcolrmcolumncommcommandcompgencompletecompresscoproccpcpiocroncryptcsplitcucutdatedcdddebugfsdeclaredepmoddfdialogdiffdiff3diffstatdigdirnamedirsdisowndmesgdoexecdos2unixdudumpdumpe2fse2fsckechoegrepenableenscriptenveqnevalexecexit(相关话题:退出状态)expandexportexprfactorfalsefdformatfdiskfgfgrepfilefindfingerflexflockfmtfoldfreefsckftpfusergetfaclgetoptgetoptsgettextgettygnome-mountgrepgroffgroupmodgroups(相关话题:变量 $GROUPS)gsgziphalthashhdparmheadhelphexdumphosthostidhostname(相关话题:变量 $HOSTNAME)hwclockiconvid(相关话题:变量 $UID)ifconfiginfoinfocmpinitinsmodinstallipipcalciptablesiwconfigjobsjoinjotkillkillalllastlastcommlastloglddlessletlexlidlnlocatelockfileloggerlognamelogoutlogrotatelooklosetuplplslsdevlsmodlsoflspcilsusbltracelynxlzcatlzmam4mailmailstatsmailtomakeMAKEDEVmanmapfilemcookiemd5summergemesgmimencodemkbootdiskmkdirmkdosfsmke2fsmkfifomkisofsmknodmkswapmktempmmencodemodinfomodprobemoremountmsgfmtmvncnetconfignetstatnewgrpnicenlnmnmapnohupnslookupobjdumpodopensslpasswdpastepatch(相关话题:diff)pathchkpaxpgreppidofpingpkillpopdprprintenvprintfprocinfopspstreeptxpushdpwd(相关话题:变量 $PWD)quotarcprdevrdistreadreadelfreadlinkreadonlyrebootrecodereniceresetresizerestorerevrloginrmrmdirrmmodrouterpmrpm2cpiorshrsyncrunlevelrun-partsrxrzsarscpscriptsdiffsedseqservicesetsetfaclsetquotasetserialsettermsha1sumsharshoptshredshutdownsizeskillsleepslocatesnicesortsourcesoxsplitsqsshstatstracestringsstripsttysusudosumsuspendswapoffswaponsxsyncsztactailtartbltcpdumpteetelinittelnetTextexexectimetimestmpwatchtoptouchtputtrtraceroutetruetsettsortttytune2fstypetypesetulimitumaskumountunameunarcunarjuncompressunexpanduniqunitsunlzmaunrarunsetunsqunzipuptimeusbmodulesuseradduserdelusermodusersusleepuucpuudecodeuuencodeuuxvacationvdirvmstatvrfywwaitwallwatchwcwgetwhatiswhereiswhichwhowhoamiwhoiswritexargsxrandrxzyaccyeszcatzdiffzdumpzegrepzfgrepzgrepzipBash是唯一被允许执行的shell脚本语言。
可执行文件必须以#!/bin/bash和最小数量的标志开始。请使set来设置shell的选项,使得用bash <script_name>调用你的脚本时不会破坏其功能。
限制所有的可执行shell脚本为bash使得我们安装在所有计算机中的shell语言保持一致性。
| 退出代码 | 表意 | 示例 | 注释 |
|---|---|---|---|
| 1 | 通用错误 | let "var1 = 1/0" | 其他错误,如除以零错误及其他无权限操作。 |
| 2 | (据 Bash 文档) 误用 Shell builtins | empty_function() {} | 缺失关键词或指令,或权限问题 (及 diff 在二进制文件比较时的返回值) |
| 126 | 调用的指令无法执行 | /dev/null | 权限问题或命令不可执行 |
| 127 | 「未找到指令」 | illegal_command | 可能是 $PATH 有问题或输入有误。 |
| 128 | exit 的参数有误 | exit 3.14159 | exit 只接受范围在 0 - 255 的整数 (见第一个脚注) |
| 128+n | 错误信号 “n” | 脚本的 kill -9 $PPID | $? 返回 137 (128 + 9) |
| 130 | 脚本被 Control-C 终止 | Ctl-C | Control-C 是错误信号 2 (130 = 128 + 2, 见上) |
| 255* | 错误状态超范围 | exit -1 | exit 只接受范围在 0 - 255 的整数 |
传统上,这类书的附录会有一个 ASCII 表。但本书不会。取而代之的是这些生成一张完整 ASCII 表的简短脚本。
例 T-1. 一个生成 ASCII 表的脚本
#!/bin/bash
# ascii.sh
# ver. 0.2, reldate 26 Aug 2008
# Patched by ABS Guide author.
# Original script by Sebastian Arming.
# Used with permission (thanks!).
exec >ASCII.txt # Save stdout to file,
#+ as in the example scripts
#+ reassign-stdout.sh and upperconv.sh.
MAXNUM=256
COLUMNS=5
OCT=8
OCTSQU=64
LITTLESPACE=-3
BIGSPACE=-5
i=1 # Decimal counter
o=1 # Octal counter
while [ "$i" -lt "$MAXNUM" ]; do # We don't have to count past 400 octal.
paddi=" $i"
echo -n "${paddi: $BIGSPACE} " # Column spacing.
paddo="00$o"
# echo -ne "\\${paddo: $LITTLESPACE}" # Original.
echo -ne "\\0${paddo: $LITTLESPACE}" # Fixup.
# ^
echo -n " "
if (( i % $COLUMNS == 0)); then # New line.
echo
fi
((i++, o++))
# The octal notation for 8 is 10, and 64 decimal is 100 octal.
(( i % $OCT == 0)) && ((o+=2))
(( i % $OCTSQU == 0)) && ((o+=20))
done
exit $?
# Compare this script with the "pr-asc.sh" example.
# This one handles "unprintable" characters.
# Exercise:
# Rewrite this script to use decimal numbers, rather than octal.
没有任何一种程序设计语言是完美的,甚至没有一个最好的语言。只有在特定环境下适合的语言。
—— Herbert Mayer
无论你是否打算真正编写shell脚本,只要你想要在一定程度上熟悉系统管理,了解掌握shell脚本的相关知识都是非常有必要的。例如Linux系统在启动的时候会执行/etc/rc.d目录下的shell脚本来恢复系统配置和准备服务。详细了解这些启动脚本对分析系统行为大有益处,何况,你很有可能会去修改它们呢。
写完一个脚本以后,你可以通过sh scriptname或bash scriptname来调用它(不推荐使用sh <scriptname调用脚本,因为这会禁用脚本从标准输入(stdin)读入数据)。更方便的方式是使用chmod命令使脚本可以被直接执行。
执行命令:
chmod 555 scriptname(给予所有用户读取/执行的权限)
或
chmod +rx scriptname(给予所有用户读取/执行的权限)
脚本:文章;书面文档
——韦伯斯特字典1913年版
Shell是一种命令解释器,它不仅分离了用户层与操作系统内核,更是一门强大的编程语言。我们称为shell编写的程序为脚本(script)。脚本是一种易于使用的工具,它能够将系统调用、工具软件、实用程序(utility)和已编译的二进制文件联系在一起构建程序。实际上,shell脚本可以调用所有的UNIX命令、实用程序以及工具软件。如果你觉得这还不够,使用像test命令和循环结构这样的shell内建命令能够让脚本更加灵活强大。Shell脚本特别适合完成系统管理任务和那些不需要复杂结构性语言实现的重复工作。