news 2025/12/28 22:42:27

47、Bash编程:避免常见错误与掌握关键特性

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
47、Bash编程:避免常见错误与掌握关键特性

Bash编程:避免常见错误与掌握关键特性

避免函数调用时“command not found”错误

在编程中,不同的编程语言对于函数调用和定义有不同的规则。比如在Perl等语言中,你可以在函数实际定义之前的代码部分调用函数。然而,在Shell脚本中,情况有所不同。

问题:习惯了像Perl这样允许在函数定义前调用函数的语言,在Shell脚本中沿用这种方式可能会导致“command not found”错误。
解决方案:Shell脚本是按从上到下的线性方式读取和执行的,所以在使用函数之前必须先定义它们。
原因分析:一些语言(如Perl)在执行过程中会有中间步骤,将整个脚本作为一个单元进行解析,这使得你可以将main()函数放在代码顶部,而将其他函数或子例程放在后面定义。但Shell脚本是先读入内存,然后逐行执行,因此在定义函数之前无法使用它。

区分Shell通配符和正则表达式

在Shell编程中,通配符和正则表达式容易让人混淆。有时候会看到.**[a - z]*等符号,但它们的含义可能和你预期的不同,而且在grepsed中使用正则表达式,在bash的某些地方却不适用,这让人难以理清。

问题:难以区分Shell通配符和正则表达式的使用场景和含义。
解决方案:放松心态,可能是因为学习的内容太多或者使用频率太低而导致混淆,多练习就会逐渐掌握。在bash中,正则表达式语法仅在=~比较运算符中使用,其他表达式都使用Shell模式匹配。
详细说明bash使用的模式匹配和正则表达式有一些相同的符号,但含义不同。而且在Shell脚本中,经常会调用使用正则表达式的命令,如grepsed。经过询问专家得知,=~bash中唯一使用正则表达式的地方。以下是bash中使用Shell模式匹配的部分语法:
- 文件名通配(路径名扩展)
-[[中的==!=运算符
-case语句
-$GLOBIGNORE处理
-$HISTIGNORE处理
-${parameter#[#]word}
-${parameter%[%]word}
-${parameter/pattern/string}
- 几个可绑定的readline命令(如glob-expand-wordglob-complete-word等)
-complete -Gcompgen -G
-complete -Xcompgen -X
-help内置命令的pattern参数

Bash调用选项

在调用当前版本的bash时,可以使用以下选项。多字符选项必须在单字符选项之前出现在命令行上。登录Shell通常使用-i(交互式)、-s(从标准输入读取)和-m(启用作业控制)选项。除了表中列出的选项外,任何set选项都可以在命令行上使用。

OptionMeaning
-c string如果存在string,则从string中读取命令。string之后的任何参数都将被解释为位置参数,从$0开始。
-D将所有以$开头的双引号字符串列表打印到标准输出。当当前区域设置不是CPOSIX时,这些字符串会进行语言翻译。同时开启-n选项。
-i交互式Shell。忽略TERMINTQUIT信号。如果启用作业控制,也会忽略TTINTTOUTSTP信号。
-l使bash表现得像作为登录Shell被调用一样。
-o option接受与set -o相同的参数。
-O, +O shopt-optionshopt-optionshopt内置命令接受的Shell选项之一。如果存在shopt-option-O设置该选项的值;+O取消设置。如果未提供shopt-option,则将shopt接受的Shell选项的名称和值打印到标准输出。如果调用选项是+O,输出将以可作为输入重用的格式显示。
-s从标准输入读取命令。如果给bash提供了参数,此标志优先(即参数不会被视为脚本名称,而是从标准输入读取)。
-r受限Shell。
-v读取Shell输入行时将其打印出来。
-表示选项结束,禁用进一步的选项处理。此后的任何选项都将被视为文件名和参数。---同义。
–debugger安排在Shell启动前执行调试器配置文件。在bash 3.0或更高版本中开启扩展调试模式和Shell函数跟踪。
–dump-strings-D作用相同。
–dump-po-strings-D作用相同,但输出采用GNU gettext可移植对象(po)文件格式。
–help显示使用消息并退出。
–login使bash表现得像作为登录Shell被调用一样,与-l相同。
–noediting如果是交互式Shell,不使用GNU readline库读取命令行。
–noprofile不读取启动文件/etc/profile或任何个人初始化文件。
–norc如果是交互式Shell,不读取初始化文件~/.bashrc。如果以sh调用Shell,此选项默认开启。
–posixbash的默认操作与POSIX标准不同的地方,使bash的行为更符合POSIX标准。
–quiet启动Shell时不显示任何信息,这是默认行为。
–rcfile file, –init-file file如果是交互式Shell,执行从file读取的命令,而不是初始化文件~/.bashrc
–verbose等同于-v
–version显示此bash实例的版本号,然后退出。
提示字符串自定义

以下是可用的提示字符串自定义格式代码的总结,不同的bash版本对这些代码的支持有所不同。

CommandMeaningAdded
\aASCII铃字符(007)bash - 1.14.7
\A当前时间,24小时制的HH:MM格式bash - 2.05
\d“星期 月份 日期”格式的日期
\D {format}format传递给strftime(3),并将结果插入提示字符串;空格式会得到特定于区域设置的时间表示;需要使用花括号bash - 2.05b
\eASCII转义字符(033)bash - 1.14.7
\H主机名bash - 1.14.7
\h主机名,直到第一个“.”
\j当前Shell管理的作业数量bash - 2.03
\lShell终端设备名称的基本名称bash - 2.03
\n回车换行符
\r回车符bash - 2.01.1
\sShell的名称
\T当前时间,12小时制的HH:MM:SS格式bash - 1.14.7
\t当前时间,HH:MM:SS格式
\@当前时间,12小时制的a.m./p.m.格式bash - 1.14.7
\u当前用户的用户名
\vbash的版本号(如2.00)bash - 1.14.7
\Vbash的发行号;版本和补丁级别(如3.00.0)bash - 1.14.7
\w当前工作目录
\W当前工作目录的基本名称
#当前命令的命令编号
!当前命令的历史编号
\$如果有效用户ID为0,打印#,否则打印$
\nnn八进制字符代码
\打印反斜杠
[开始非打印字符序列,如终端控制序列
]结束非打印字符序列
ANSI颜色转义序列

以下是ANSI颜色转义序列的相关信息,可用于设置终端输出的颜色和字符属性。

CodeCharacter attributeFG codeForeground colorBG codeBackground color
0重置所有属性30黑色40黑色
1明亮31红色41红色
2暗淡32绿色42绿色
4下划线33黄色43黄色
5闪烁34蓝色44蓝色
7反转35品红色45品红色
8隐藏36青色46青色
37白色47白色

Bash编程:避免常见错误与掌握关键特性

内置命令和保留字

以下是所有内置命令和保留字的总结,表格中“Type”列的字母含义为:R = 保留字,空白 = 内置命令。

CommandTypeSummary
!R命令退出状态的逻辑非。
:不执行任何操作(仅对参数进行扩展)。
.读取文件并在当前Shell中执行其内容。
alias为命令或命令行设置简写。
bg将作业放入后台。
bind将键序列绑定到readline函数或宏。
break从周围的forselectwhileuntil循环中退出。
builtin执行指定的Shell内置命令。
caseR保留字,多路条件构造。
cd更改工作目录。
command绕过Shell函数查找来运行命令。
compgen生成可能的补全匹配项。
complete指定补全的执行方式。
continue跳过forselectwhileuntil循环的下一次迭代。
declare声明变量并赋予其属性,与typeset相同。
dirs显示当前记住的目录列表。
disown从作业表中移除作业。
doRforselectwhileuntil循环构造的一部分。
doneRforselectwhileuntil循环构造的一部分。
echo输出参数。
elifRif构造的一部分。
elseRif构造的一部分。
enable启用和禁用内置Shell命令。
esacRcase构造的结束。
eval通过命令行处理运行给定的参数。
exec用给定的程序替换Shell。
exit从Shell退出。
export创建环境变量。
fc修复命令(编辑历史文件)。
fg将后台作业置于前台。
fiRif构造的一部分。
forR循环构造。
functionR定义函数。
getopts处理命令行选项。
hash确定并记住全路径名。
help显示内置命令的帮助信息。
history显示命令历史。
ifR条件构造。
inRcase构造的一部分。
jobs列出任何后台作业。
kill向进程发送信号。
let算术变量赋值。
local创建局部变量。
logout退出登录Shell。
popd从目录栈中移除目录。
pushd向目录栈中添加目录。
pwd打印工作目录。
read从标准输入读取一行。
readonly使变量只读(不可赋值)。
return从周围的函数或脚本返回。
selectR菜单生成构造。
set设置选项。
shift移动命令行参数。
suspend暂停Shell的执行。
test计算条件表达式。
thenRif构造的一部分。
timeR运行命令管道并打印执行时间,输出格式可通过TIMEFORMAT控制。
times打印从Shell运行的进程的累积用户和系统时间。
trap设置信号捕获例程。
type识别命令的来源。
typeset声明变量并赋予其属性,与declare相同。
ulimit设置/显示进程资源限制。
umask设置/显示文件权限掩码。
unalias移除别名定义。
unset移除变量或函数的定义。
untilR循环构造。
wait等待后台作业完成。
whileR循环构造。
内置Shell变量

以下是bash 3.0中可用的环境变量的完整列表,表格中“Type”列的字母含义为:A = 数组,L = 冒号分隔的列表,R = 只读,U = 取消设置会使其失去特殊含义。

VariableTypeDescription
*R一个字符串,包含当前脚本或函数的位置参数,由$IFS的第一个字符分隔(例如arg1 arg2 arg3)。
@R当前脚本或函数的每个位置参数,作为双引号字符串列表给出(例如"arg1" "arg2" "arg3")。
#R当前脚本或函数的参数数量。
-R调用Shell时提供的选项。
?R上一个命令的退出状态。
_R上一个命令的最后一个参数。
$RShell进程的进程ID。
!R最后一个后台命令的进程ID。
0RShell或Shell脚本的名称。
BASH用于调用此bash实例的完整路径名。
BASH_ARGCA一个数组,其值是当前bash执行调用栈中每个帧的参数数量。当前子例程(使用.source执行的Shell函数或脚本)的参数数量位于栈顶。
BASH_ARGVA当前bash执行调用栈中的所有参数。最后一个子例程调用的最后一个参数位于栈顶;初始调用的第一个参数位于栈底。
BASH_COMMAND当前正在执行或即将执行的命令,除非Shell正在作为陷阱的结果执行命令,在这种情况下,它是陷阱发生时正在执行的命令。
BASH_EXECUTION_STRING-c调用选项的命令参数。
BASH_ENV当Shell被调用时作为环境文件运行的文件名。
BASH_LINENOA一个数组,其成员是源文件中与@var{FUNCNAME}的每个成员对应的行号。${BASHLINENO[$i]}是源文件中调用${FUNCNAME[$i + 1]}的行号,对应的源文件名是${BASHSOURCE[$i + 1]}
BASH_REMATCHAR一个数组,其成员由[[条件命令的=~二元运算符赋值。索引为0的元素是与整个正则表达式匹配的字符串部分,索引为n的元素是与第n个带括号的子表达式匹配的字符串部分。
BASH_SOURCEA一个数组,包含与$FUNCNAME数组变量中的元素对应的源文件名。
BASH_SUBSHELL每次生成子Shell或子Shell环境时递增 1,初始值为 0。子Shell是父Shell的派生副本,共享其环境。
BASH_VERSIONbash实例的版本号。
BASH_VERSINFOARbash实例的版本信息,数组的每个元素保存版本号的一部分。
CDPATHLcd命令搜索的目录列表。
COMP_CWORDCOMPWORDS中包含当前光标位置的单词的索引,此变量仅在可编程补全设施调用的Shell函数中可用。
COMP_LINE当前命令行,此变量仅在可编程补全设施调用的Shell函数和外部命令中可用。
COMP_POINT当前光标位置相对于当前命令开头的索引。如果当前光标位置在当前命令的末尾,此变量的值等于${#COMPLINE},此变量仅在可编程补全设施调用的Shell函数和外部命令中可用。
COMP_WORDBREAKSUReadline库在执行单词补全时视为单词分隔符的字符集。如果取消设置COMP_WORDBREAKS,它将失去其特殊属性,即使随后重新设置也是如此。
COMP_WORDSA当前命令行中各个单词的数组,此变量仅在可编程补全设施调用的Shell函数中可用。
COMPREPLYA可编程补全设施调用的Shell函数生成的可能补全项。
DIRSTACKARU目录栈的当前内容。
EUIDR当前用户的有效用户ID。
FUNCNAMEARU一个数组,包含当前执行调用栈中所有Shell函数的名称。索引为0的元素是当前正在执行的任何Shell函数的名称,最底部的元素是“main”,此变量仅在Shell函数执行时存在。
FCEDITfc命令的默认编辑器。
FIGNOREL执行文件名补全时要忽略的名称列表。
GLOBIGNOREL路径名扩展期间要忽略的文件名模式列表。
GROUPSAR一个数组,包含当前用户所属的组列表。
IFS内部字段分隔符,作为单词分隔符的字符列表,通常设置为空格、制表符和换行符。
HISTCMDU当前命令的历史编号。
HISTCONTROL由冒号(:)分隔的模式列表,可具有以下值:ignorespace:以空格开头的行不进入历史列表;ignoredups:与最后一个历史行匹配的行不进入;erasedups:在保存当前行之前,从历史列表中移除所有与当前行匹配的先前行;ignoreboth:同时启用ignorespaceignoredups
HISTFILE命令历史文件的名称。
HISTIGNORE决定历史列表中应保留哪些内容的模式列表。
HISTSIZE命令历史中保留的行数。
HISTFILESIZE历史文件中保留的最大行数。
HISTTIMEFORMAT如果设置且不为空,其值用作strftime(3)的格式字符串,用于打印history内置命令显示的每个历史条目的时间戳。如果设置此变量,时间戳将写入历史文件,以便在Shell会话之间保留。
HOME主(登录)目录。
HOSTFILE用于主机名补全的文件。
HOSTNAME当前主机的名称。
HOSTTYPEbash运行的机器类型。
IGNOREEOF退出交互式Shell之前接收的EOF字符数量。
INPUTRCreadline启动文件。
LANG用于确定未由以LC_开头的变量专门选择的任何类别(如LC_COLLATE、LC_CTYPE等)的区域类别。
LC_ALL覆盖$LANG和任何其他指定区域类别的LC_变量的值。
LC_COLLATE确定路径名扩展结果排序时使用的排序顺序。
LC_CTYPE确定路径名扩展和模式匹配中字符的解释和字符类的行为。
LC_MESSAGES此变量确定用于翻译以$开头的双引号字符串的区域设置。
LC_NUMERIC确定用于数字格式化的区域类别。
LINENOU脚本或函数中刚刚运行的行号。
MACHTYPE描述bash执行所在系统的字符串。
MAIL检查新邮件的文件名。
MAILCHECK检查新邮件的频率(以秒为单位)。
MAILPATHL如果未设置$MAIL,则检查新邮件的文件名列表。
OLDPWD上一个工作目录。
OPTARGgetopts处理的最后一个选项参数的值。
OPTERR如果设置为 1,显示getopts的错误消息。
OPTIND选项之后的第一个参数的编号。
OSTYPEbash执行的操作系统。
PATHL命令的搜索路径。
PIPESTATUSA一个数组变量,包含最近执行的前台管道中进程的退出状态值列表。
POSIXLY_CORRECT如果在bash启动时存在于环境中,Shell在读取启动文件之前进入POSIX模式,就像提供了--posix调用选项一样。如果在Shell运行时设置,bash启用POSIX模式,就像执行了set -o posix命令一样。
PROMPT_COMMAND在发出主提示之前,将其值作为命令执行。
PS1主命令提示字符串。
PS2行延续的提示字符串。
PS3select命令的提示字符串。
PS4xtrace选项的提示字符串。
PPIDR父进程的进程ID。
PWD当前工作目录。
RANDOMU0到32767(2^15 - 1)之间的随机数。
REPLY用户对select命令的响应;如果未给出变量名,则是read命令的结果。
SECONDSU自Shell被调用以来的秒数。
SHELLShell的完整路径名。
SHELLOPTSLR已启用的Shell选项列表。
SHLVL每次调用新的bash实例(不是子Shell)时递增 1,用于计算bashShell的嵌套深度。
TIMEFORMAT指定在命令管道上使用time保留字时输出的格式。
TMOUT如果设置为正整数,则在没有收到输入的情况下,Shell自动终止的秒数。
UIDR当前用户的用户ID。
auto_resume控制作业控制的工作方式(值为exactsubstring或其他非这些关键字的值)。
histchars指定用作历史控制字符的内容,通常设置为字符串!^#

通过掌握这些Bash的关键特性和避免常见错误,能够让你在使用Bash进行编程和脚本编写时更加得心应手,提高工作效率和代码的稳定性。希望这些内容对你有所帮助,让你在Bash的世界中探索更多的可能性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/11 7:50:45

48、深入探究Bash Shell的配置选项

深入探究Bash Shell的配置选项1. 引言在使用Bash Shell时,我们常常需要对其行为进行各种配置,以满足不同的使用场景和需求。Bash提供了丰富的配置选项,主要通过set、shopt命令以及环境变量来实现。下面将详细介绍这些配置选项及其使用方法。2…

作者头像 李华
网站建设 2025/12/11 7:50:45

49、Bash 脚本实用操作与格式化指南

Bash 脚本实用操作与格式化指南1. 测试运算符测试运算符常用于test以及[...]和[[...]]结构中。这些运算符可以通过-a(“and”)和-o(“or”)进行逻辑组合,还能使用转义括号\(...)进行分组。需要注意的是,字符…

作者头像 李华
网站建设 2025/12/11 7:50:44

50、Bash编程实用参考与示例详解

Bash编程实用参考与示例详解在Bash编程中,有许多实用的功能和工具可以提高我们的工作效率。下面我们将详细介绍一些重要的内容,包括字符类、扩展模式匹配运算符、转义序列、Readline配置以及Bash自带的示例。1. POSIX字符类POSIX字符类可以在[]中使用&am…

作者头像 李华
网站建设 2025/12/11 7:50:43

51、命令行处理与版本控制全解析

命令行处理与版本控制全解析命令行处理在使用shell时,命令行处理是一个核心环节,它涉及多个步骤,理解这些步骤对于成为shell脚本编写专家或解决复杂问题至关重要。命令行处理步骤每一行从标准输入(STDIN)或脚本中读取的…

作者头像 李华
网站建设 2025/12/28 8:58:44

52、版本控制工具综合指南

版本控制工具综合指南 1. 版本控制概述 版本控制在软件开发和文档管理中至关重要,它能帮助我们跟踪文件的变化、恢复到旧版本、协作开发等。常见的版本控制工具有 CVS、Subversion、RCS 等,不同的工具各有优缺点,适用于不同的场景。 2. CV…

作者头像 李华
网站建设 2025/12/11 7:50:41

53、从源码构建bash及相关操作指南

从源码构建bash及相关操作指南 1. 获取bash 如果你能直接连接互联网,获取bash应该不成问题。bash主页位于 http://www.gnu.org/software/bash/bash.html ,从这里你可以找到当前发行版的最新详细信息以及获取途径。 若无法直接联网,你也可…

作者头像 李华