替代Shell使用指南
在Linux系统中,除了常见的Bash shell,还有其他一些功能独特的shell可供选择,如Dash shell和zsh shell。了解这些替代shell的特点和使用方法,对于编写和运行shell脚本非常有帮助。
1. Dash Shell 特性
Dash shell和Bash shell都基于Bourne shell开发,但它们之间存在一些差异。在编写可能需要在Ubuntu环境中运行的Bash shell脚本时,了解这些差异尤为重要。
1.1 Dash命令行参数
Dash shell使用命令行参数来控制其行为,Debian在原始ash shell命令行参数列表中添加了一些额外的参数。以下是Dash命令行参数及其说明:
| 参数 | 描述 |
| ---- | ---- |
| -a | 导出所有分配给shell的变量 |
| -c | 从指定的命令字符串中读取命令 |
| -e | 如果是非交互式的,任何未测试的命令失败时立即退出 |
| -f | 显示路径名通配符字符 |
| -n | 如果是非交互式的,读取命令但不执行 |
| -u | 尝试展开未设置的变量时,向STDERR写入错误消息 |
| -v | 读取输入时将其写入STDERR |
| -x | 执行每个命令时将其写入STDERR |
| -I | 交互式模式下忽略输入中的EOF字符 |
| -i | 强制shell以交互式模式运行 |
| -m | 开启作业控制(交互式模式下默认启用) |
| -s | 从STDIN读取命令(如果没有文件参数,这是默认行为) |
| -E | 启用Emacs命令行编辑器 |
| -V | 启用vi命令行编辑器 |
其中,-E参数允许使用Emacs编辑器命令来编辑命令行文本,可通过Ctrl和Alt键组合使用所有Emacs单行文本操作命令;-V参数允许使用vi编辑器命令编辑命令行文本,通过按Esc键在正常模式和vi编辑器模式之间切换,在vi编辑器模式下可使用标准vi编辑器命令,编辑完成后再次按Esc键退出。
1.2 Dash环境变量
Dash shell使用许多默认环境变量来跟踪信息,也可以创建自己的环境变量。
-
默认环境变量
:Dash环境变量与Bash环境变量非常相似,因为它们都是Bourne shell的扩展,但Dash shell为了追求简单性,包含的环境变量明显少于Bash。可以使用
set
命令显示环境变量,不同Linux发行版在登录时分配的默认环境变量可能不同。
$ set
COLORTERM=''
DESKTOP_SESSION='default'
DISPLAY=':0.0'
DM_CONTROL='/var/run/xdmctl'
GS_LIB='/home/atest/.fonts'
HOME='/home/atest'
IFS='
'
KDEROOTHOME='/root/.kde'
KDE_FULL_SESSION='true'
KDE_MULTIHEAD='false'
KONSOLE_DCOP='DCOPRef(konsole-5293,konsole)'
KONSOLE_DCOP_SESSION='DCOPRef(konsole-5293,session-1)'
LANG='en_US'
LANGUAGE='en'
LC_ALL='en_US'
LOGNAME='atest'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='5293'
PS1='$ '
PS2='> '
PS4='+ '
PWD='/home/atest'
SESSION_MANAGER='local/testbox:/tmp/.ICE-unix/5051'
SHELL='/bin/dash'
SHLVL='1'
TERM='xterm'
USER='atest'
XCURSOR_THEME='default'
_='ash'
$
-
位置参数
:除了默认环境变量,Dash shell会为命令行中定义的任何参数分配特殊变量,这些位置参数变量与Bash shell中的类似,可在shell脚本中像在Bash shell中一样使用。
-
$0:shell脚本的名称 -
$n:第n个位置参数 -
$*:一个包含所有参数内容的单值,由IFS环境变量的第一个字符分隔,如果IFS未定义则用空格分隔 -
$@:扩展为包含所有命令行参数的多个参数 -
$#:位置参数的数量 -
$?:最近命令的退出状态 -
$-:当前选项标志 -
$$:当前shell的进程ID(PID) -
$!:最近后台命令的进程ID(PID)
-
-
用户定义的环境变量
:可以在命令行上使用赋值语句定义新的环境变量,使用
export命令可使变量在所有子shell中可用,否则仅在当前shell或进程中可见。需要注意的是,Dash shell不支持变量数组,这给高级shell脚本编写者带来了一些问题。
$ testing=10 ; export testing
$ echo $testing
10
$
1.3 Dash内置命令
Dash shell包含一组内置命令,可直接从命令行界面使用,也可包含在shell脚本中。以下是Dash shell内置命令及其说明:
| 命令 | 描述 |
| ---- | ---- |
| alias | 创建一个别名字符串来表示一个文本字符串 |
| bg | 在后台模式下继续指定的作业 |
| cd | 切换到指定的目录 |
| echo | 显示文本字符串和环境变量 |
| eval | 用空格连接所有参数 |
| exec | 用指定的命令替换shell进程 |
| exit | 终止shell进程 |
| export | 导出指定的环境变量供所有子shell使用 |
| fc | 列出、编辑或重新执行之前在命令行中输入的命令 |
| fg | 在前台模式下继续指定的作业 |
| getopts | 从参数列表中获取选项和参数 |
| hash | 维护和检索最近命令及其位置的哈希表 |
| pwd | 显示当前工作目录的值 |
| read | 从STDIN读取一行并将值分配给变量 |
| readonly | 从STDIN读取一行到一个不可更改的变量 |
| printf | 使用格式化字符串显示文本和变量 |
| set | 列出或设置选项标志和环境变量 |
| shift | 将位置参数移动指定的次数 |
| test | 计算表达式,如果为真返回0,否则返回1 |
| times | 显示shell和所有shell进程的累积用户和系统时间 |
Dash shell支持许多与Bash shell相同的内置命令,但不支持命令历史文件或目录栈相关的命令。
1.4 Dash脚本编写
Dash shell并不识别Bash shell的所有脚本特性,为Bash环境编写的shell脚本在Dash shell中运行时常常失败。
- 创建Dash脚本 :创建Dash shell脚本与创建Bash shell脚本类似,应在脚本的第一行指定要使用的shell:
#!/bin/dash
也可以在这一行指定shell命令行参数。
-
不适用的特性 :由于Dash shell只是Bourne shell特性的一个子集,Bash shell脚本中的一些特性在Dash shell中不起作用,这些特性通常被称为Bashisms。
| 命令 | 描述 |
| ---- | ---- |
| trap | 当shell接收到指定信号时解析并执行操作 |
| type | 解释指定的名称并显示解析结果(别名、内置命令、命令、关键字) |
| ulimit | 查询或设置进程的限制 |
| umask | 设置默认文件和目录权限的值 |
| unalias | 删除指定的别名 |
| unset | 从导出的变量中删除指定的变量或选项标志 |
| wait | 等待指定的作业完成并返回退出状态 | -
算术运算 :在Bash shell脚本中有三种表达数学运算的方式:使用
expr命令、方括号$[ operation ]和双括号$(( operation ))。Dash shell支持expr命令和双括号方法,但不支持方括号方法。在Dash shell脚本中执行数学运算的正确格式是使用双括号方法。
$ cat test1
#!/bin/dash
# testing mathematical operations
value1=10
value2=15
value3=$(( $value1 * $value2 ))
echo "The answer is $value3"
$ ./test1
The answer is 150
$
-
test命令
:Dash shell支持
test命令,但使用时需注意,Bash shell的test命令允许使用双等号==测试两个字符串是否相等,而Dash shell的test命令只识别单等号=。如果在Bash脚本中使用了==,需要将文本比较符号改为单等号。
$ cat test2
#!/bin/dash
# testing the = comparison
test1=abcdef
test2=abcdef
if [ $test1 = $test2 ]
then
echo "They're the same!"
else
echo "They're different"
fi
$ ./test2
They're the same!
$
-
函数命令
:Bash shell支持两种定义函数的方法:使用
function语句和仅使用函数名。Dash shell不支持function语句,必须使用函数名后跟括号来定义函数。如果编写的shell脚本可能在Dash环境中使用,应始终使用函数名来定义函数。
$ cat test3
#!/bin/dash
# testing functions
func1() {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$(( $count + 1 ))
done
echo "This is the end of the loop"
func1
echo "This is the end of the script"
$ ./test3
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is the end of the loop
This is an example of a function
This is the end of the script
$
2. zsh Shell 特性
zsh shell是由Paul Falstad开发的开源Unix shell,它借鉴了所有现有shell的思想,并添加了许多独特的功能,是为程序员设计的高级shell。
2.1 zsh的独特特性
-
改进的shell选项处理
:zsh shell使用选项来定制shell的行为,可在命令行或shell内部使用
set命令设置。 - shell兼容模式 :可以设置zsh shell的行为来模仿其他类型shell的行为。
- 可加载模块 :zsh shell提供了一组核心内置命令,还可以添加额外的命令模块,每个模块为特定情况提供一组额外的内置命令,如网络支持和高级数学函数。可以根据具体情况添加所需的模块,这既可以在需要小shell大小和少量命令的情况下限制zsh shell的大小,也可以在需要更快执行速度的情况下扩展可用内置命令的数量。
2.2 zsh命令行参数
zsh shell使用一些命令行参数来定义其操作,以下是zsh命令行参数及其说明:
| 参数 | 描述 |
| ---- | ---- |
| -c | 仅执行指定的命令并退出 |
| -i | 以交互式shell启动,提供命令行界面提示 |
| -s | 强制shell从STDIN读取命令 |
| -o | 指定命令行选项 |
其中,-o参数允许设置定义shell内部特性的选项,zsh shell是最可定制的shell之一,其选项分为多个一般类别:
-
更改目录
:控制
cd
和
dirs
命令处理目录更改的选项
-
补全
:控制命令补全功能的选项
-
扩展和通配
:控制命令中文件扩展的选项
-
历史记录
:控制命令历史记录召回的选项
-
初始化
:控制shell启动时如何处理变量和启动文件的选项
-
输入/输出
:控制命令处理的选项
-
作业控制
:规定shell如何处理和启动作业的选项
-
提示
:定义shell如何处理命令行提示的选项
-
脚本和函数
:控制shell如何处理shell脚本和定义shell函数的选项
-
shell仿真
:允许设置zsh shell的行为以模仿其他类型shell的行为的选项
-
shell状态
:定义启动何种类型shell的选项
-
zle
:控制zsh行编辑器(zle)功能的选项
-
选项别名
:可作为其他选项名称别名的特殊选项
2.3 zsh内置命令
zsh shell允许扩展可用的内置命令,提供了丰富的快速实用工具。以下是zsh核心内置命令及其说明:
| 命令 | 描述 |
| ---- | ---- |
| alias | 为命令和参数定义别名 |
| autoload | 将shell函数预加载到内存中以便快速访问 |
| bg | 在后台模式下执行作业 |
| bindkey | 将键盘组合绑定到命令 |
| builtin | 执行指定的内置命令而不是同名的可执行文件 |
| bye | 与exit相同 |
| cd | 更改当前工作目录 |
| chdir | 更改当前工作目录 |
| command | 将指定的命令作为外部文件执行,而不是函数或内置命令 |
| declare | 设置变量的数据类型(与typeset相同) |
| dirs | 显示目录栈的内容 |
| disable | 临时禁用指定的哈希表元素 |
| disown | 从作业表中删除指定的作业 |
| echo | 显示变量和文本 |
| emulate | 设置zsh以模仿另一个shell,如Bourne、Korn或C shell |
| enable | 启用指定的哈希表元素 |
| eval | 在当前shell进程中执行指定的命令和参数 |
| exec | 执行指定的命令和参数,替换当前shell进程 |
| exit | 以指定的退出状态退出shell,如果未指定,则使用最后一个命令的退出状态 |
| export | 允许指定的环境变量名称和值在子shell进程中使用 |
| false | 返回退出状态1 |
| fc | 从历史列表中选择一系列命令 |
| fg | 在前台模式下执行指定的作业 |
| float | 将指定的变量设置为浮点变量 |
| functions | 将指定的名称设置为函数 |
| getln | 读取缓冲区栈中的下一个值并将其放入指定的变量中 |
| getopts | 从命令行参数中检索下一个有效选项并将其放入指定的变量中 |
| hash | 直接修改命令哈希表的内容 |
| history | 列出历史文件中包含的命令 |
| integer | 将指定的变量设置为整数值 |
| jobs | 列出指定作业的信息,或分配给shell进程的所有作业的信息 |
| kill | 向指定的进程或作业发送信号(默认SIGTERM) |
| let | 计算数学运算并将结果分配给变量 |
| limit | 设置或显示资源限制 |
| local | 设置指定变量的数据特征 |
| log | 显示当前登录的所有受watch参数影响的用户 |
| logout | 与exit相同,但仅在shell是登录shell时有效 |
| popd | 从目录栈中删除下一个条目 |
| print | 显示变量和文本 |
| printf | 使用C风格的格式字符串显示变量和文本 |
| pushd | 更改当前工作目录,并将上一个目录放入目录栈中 |
| pushln | 将指定的参数放入编辑缓冲区栈中 |
| pwd | 显示当前工作目录的完整路径名 |
| read | 读取一行并使用IFS字符将数据字段分配给指定的变量 |
| readonly | 将一个值分配给一个不可更改的变量 |
| rehash | 重建命令哈希表 |
| set | 设置shell的选项或位置参数 |
| setopt | 设置shell的选项 |
| shift | 读取并删除第一个位置参数,然后将其余参数向下移动一个位置 |
| source | 找到指定的文件并将其内容复制到当前位置 |
| suspend | 暂停shell的执行,直到收到SIGCONT信号 |
| test | 如果指定的条件为真,则返回退出状态0 |
| times | 显示shell和在shell中运行的进程的累积用户和系统时间 |
| trap | 阻止shell处理指定的信号,如果收到信号则执行指定的命令 |
| true | 返回退出状态0 |
| ttyctl | 锁定和解锁显示 |
| type | 显示shell如何解释指定的命令 |
| typeset | 设置或显示变量的属性 |
| ulimit | 设置或显示shell或在shell中运行的进程的资源限制 |
| umask | 设置或显示创建文件和目录的默认权限 |
| unalias | 删除指定的命令别名 |
| unfunction | 删除指定的已定义函数 |
| unhash | 从哈希表中删除指定的命令 |
| unlimit | 删除指定的资源限制 |
| unset | 删除指定的变量属性 |
| unsetopt | 删除指定的shell选项 |
| wait | 等待指定的作业或进程完成 |
| whence | 显示shell如何解释指定的命令 |
| where | 如果shell找到指定的命令,则显示其路径名 |
| which | 使用csh shell风格的输出显示指定命令的路径名 |
| zcompile | 编译指定的函数或脚本以加快自动加载速度 |
| zmodload | 对可加载的zsh模块执行操作 |
通过了解Dash shell和zsh shell的特性和使用方法,可以根据具体需求选择合适的shell,提高shell脚本的编写和运行效率。
替代Shell使用指南(续)
3. Dash与zsh对比总结
为了更清晰地了解Dash shell和zsh shell的差异,下面通过表格进行对比总结:
| 对比项 | Dash shell | zsh shell |
| ---- | ---- | ---- |
| 设计目标 | 追求简单性,适合对资源要求较低的场景 | 为程序员设计,功能丰富、可定制性强 |
| 命令行参数 | 有特定的参数控制行为,如 -E、-V 用于编辑模式 | 部分参数控制操作,-o 参数可设置丰富选项 |
| 环境变量 | 环境变量数量少于Bash,不支持变量数组 | 支持用户根据需求定制环境变量相关设置 |
| 内置命令 | 支持常见内置命令,但无命令历史文件和目录栈相关命令 | 核心内置命令丰富,还可通过加载模块扩展 |
| 脚本兼容性 | 不支持Bash的部分脚本特性,存在Bashisms问题 | 有兼容模式可模仿其他shell行为 |
| 算术运算 | 支持 expr 命令和双括号方法,不支持方括号方法 | 具备更灵活的算术运算支持 |
4. 使用场景建议
不同的shell适用于不同的使用场景,下面根据具体需求给出使用建议:
-
Dash shell
-
资源受限环境
:如果系统资源有限,如嵌入式系统或对内存和CPU使用有严格要求的服务器,Dash shell因其简单性和较少的资源占用是一个不错的选择。
-
简单脚本执行
:对于只需要执行基本命令和简单逻辑的脚本,Dash shell能够满足需求,并且执行速度可能更快。
-
zsh shell
-
开发和编程场景
:zsh shell丰富的功能和可定制性使其非常适合开发人员和程序员。可通过加载模块添加网络支持、高级数学函数等功能,提高开发效率。
-
个性化需求
:如果用户希望根据自己的使用习惯对shell进行深度定制,如自定义命令补全、提示信息等,zsh shell是更好的选择。
5. 操作流程示例
为了帮助读者更好地使用Dash shell和zsh shell,下面给出一些具体的操作流程示例。
5.1 Dash shell脚本编写与执行流程
graph LR
A[创建脚本文件] --> B[指定使用Dash shell]
B --> C[编写脚本内容]
C --> D[保存脚本文件]
D --> E[赋予执行权限]
E --> F[执行脚本]
具体步骤如下:
1.
创建脚本文件
:使用文本编辑器(如
vim
)创建一个新的脚本文件,例如
test.sh
。
vim test.sh
- 指定使用Dash shell :在脚本文件的第一行添加以下内容,指定使用Dash shell。
#!/bin/dash
- 编写脚本内容 :根据需求编写脚本逻辑,例如进行数学运算。
value1=10
value2=15
value3=$(( $value1 * $value2 ))
echo "The answer is $value3"
-
保存脚本文件
:在
vim编辑器中,按下Esc键,输入:wq保存并退出。 -
赋予执行权限
:使用
chmod命令为脚本文件赋予执行权限。
chmod +x test.sh
- 执行脚本 :在终端中执行脚本。
./test.sh
5.2 zsh shell模块加载流程
graph LR
A[检查zsh是否安装] --> B[安装zsh(若未安装)]
B --> C[查找所需模块]
C --> D[加载模块]
D --> E[验证模块是否加载成功]
具体步骤如下:
1.
检查zsh是否安装
:在终端中输入
zsh --version
,如果显示版本信息,则表示已安装;否则需要进行安装。
2.
安装zsh(若未安装)
:不同Linux发行版安装方式不同,以Ubuntu为例,使用以下命令安装。
sudo apt-get install zsh
- 查找所需模块 :了解自己需要的功能模块,例如网络支持模块。
-
加载模块
:在zsh shell中使用
zmodload命令加载模块。
zmodload zsh/net/socket
- 验证模块是否加载成功 :可以通过执行与该模块相关的命令来验证是否加载成功。
6. 常见问题及解决方法
在使用Dash shell和zsh shell过程中,可能会遇到一些常见问题,下面给出相应的解决方法。
6.1 Dash shell
- Bashisms问题 :如果在Dash shell中运行Bash脚本出现错误,检查脚本中是否使用了Dash不支持的特性,如双等号比较、方括号算术运算等,将其修改为Dash支持的格式。
- 变量数组问题 :由于Dash shell不支持变量数组,在编写脚本时避免使用数组相关操作。
6.2 zsh shell
- 模块加载失败 :检查模块名称是否正确,确保模块存在于系统中。如果仍然失败,可能是系统缺少相关依赖,需要安装相应的依赖库。
- 选项设置冲突 :当设置多个选项时,可能会出现选项之间的冲突。仔细检查选项设置,根据需求调整选项的优先级。
通过以上对Dash shell和zsh shell的详细介绍、对比、使用场景建议、操作流程示例以及常见问题解决方法,希望读者能够根据自己的需求选择合适的shell,并在实际使用中更加得心应手。在实际应用中,不断探索和尝试这些shell的功能,将有助于提高工作效率和编程体验。
超级会员免费看

被折叠的 条评论
为什么被折叠?



