Zsh 与 Bash 脚本。 有什么不同?

当谈到类 Unix 操作系统上的 shell 脚本时,有两种 shell 占主导地位:Bash (Bourne Again Shell) 和 Zsh (Z Shell)。 如果您是程序员或系统管理员,两者之间的选择会极大地影响您的效率和生产力。

了解这两个 shell 之间的差异和相似之处将帮助您优化命令行工作流程。 了解每种外壳的细微差别将帮助您做出明智的决定。

什么是 Bash 和 Zsh?

Bash 在 Linux 和 macOS 系统上都很流行。 它是一个功能强大的工具,可用于与操作系统交互并运行命令。 您还可以使用 Bash 进行 shell 脚本编写,它通过编写包含多个命令的脚本来自动执行任务。

Zsh(Z shell)是 Bash 的扩展版本,具有更多功能。 它是 macOS 上的默认 shell。 它在 Linux 系统上也变得越来越流行。

如何从 Bash 切换到 Zsh

如果您使用的是 Linux 系统并想切换到 Zsh,请首先使用包管理器来安装它。 例如,在 Debian 或 Ubuntu 上,使用以下命令:

 sudo apt install zsh 

在系统上安装后,通过运行以下命令切换到它:

 chsh -s $(which zsh) 

如果您使用的是 macOS,则已经安装了 Zsh。 要切换到它,请运行以下命令:

 chsh -s /bin/zsh 

要切换回 Bash,请将上述命令中的 Zsh 替换为 Bash。

要检查您正在使用哪个 shell,请运行以下命令:

 echo $SHELL 

这将帮助您确认您正在使用您想要的 shell。

Zsh 和 Bash 之间的区别

Zsh 和 Bash 之间存在一些差异。 考虑这些差异将帮助您决定哪种外壳最适合您。

1. 快速定制

Zsh 提供了一种更简单的方法来使用基于 % 的转义序列自定义提示。 这允许带有颜色和信息的动态提示。 要自定义 shell 提示符,请定义 PS1(主提示符)。

 PS1="%F{green}%n@%m %F{blue}%~ %f$ "

上面的自定义提示以不同的颜色显示用户名、主机名和当前目录:

还有许多其他方法可以自定义 Zsh 提示符,让您设置管理指示器,包括日期和时间,并保存新提示符。

Bash 在提示定制方面使用了稍微不同的方法。 它使用转义码来指定提示中的颜色和格式更改。 要实现与上面的 Zsh 相同的自定义,您可以使用以下自定义提示。

 PS1="\[\033[32m\]\u@\h \[\033[34m\]\w \[\033[0m\]\$ "

使用 \[\033[0m\] 至关重要,因为它确保颜色变化不会影响提示后面的文本。

2. 支持关联数组

Zsh 本身支持关联数组。 这些数组提供了一种方便的方法来关联数据,从而可以轻松组织和检索信息。 使用declare -A命令显式声明关联数组:

 # Declare an associative array in Zsh 
declare -A my_assoc_array

然后您可以将值分配给关联数组:

 my_assoc_array=(key1 value1 key2 value2)  

最后,使用它们的键访问值:

 echo $my_assoc_array[key1] # Outputs: value1 

Bash 自 4.0 版本起就包含了对关联数组的本机支持。 您声明和分配值的方式与在 Zsh 中相同。 但是当涉及到访问数组值时,您需要将键括在大括号内:

 echo "${my_assoc_array[key1]}"  

主要区别在于 Zsh 对关联数组的支持比 Bash 功能更丰富、更先进。 Zsh 允许关联数组具有各种数据类型的键,而不仅仅是字符串。 Bash 仅支持字符串键。

在 Bash 的早期版本中,您需要找到一种解决方法或使用外部工具来使用关联数组。

3. 扩展的通配模式

扩展的通配模式提供了一种强大而灵活的方法来根据各种标准选择和操作文件和目录。 当您处理复杂的文件结构或需要精确控制文件选择时,它们非常有用。

在 Zsh 脚本中,您可以使用 setopt 命令启用这些模式。 例如,要匹配当前目录中的所有 .txt 文件:

 setopt extended_glob
txt_files=(*.txt)

要匹配除 .log 扩展名之外的所有文件:

 setopt extended_glob
non_log_files=^(*.log)

在 Bash 中,您需要使用带有 extglob 选项的 shopt 命令来启用它们。 例如,要匹配当前目录中的所有 .txt 文件:

 shopt -s extglob
txt_files=(*.txt)

要匹配除 .log 扩展名之外的所有文件:

 shopt -s extglob
non_log_files=!(*.log)

在通配模式方面,Zsh 和 Bash 之间的主要区别在于用于启用它们的命令。 但请注意,两个 shell 之间的某些运算符是不同的。

4. 高级参数扩展

Zsh支持参数的间接扩展。 这允许您扩展名称存储在另一个变量中的变量的值。 为此,您需要在变量名称前添加感叹号 !。

 name="foo"
result="${!name}"
echo "$result"

另一方面,Bash 本身不允许间接扩展。 解决方法是使用 eval 内置命令或 ${!var} 语法进行间接变量引用。

 name="world"
var="name"
echo ${!var} # This will output: world

Bash 和 Zsh 之间的相似之处

虽然 Bash 和 Zsh 之间存在差异,但它们也有一些相似之处。

1. 命令行语法

Bash 和 Zsh 共享相似的命令行语法。 这很棒,因为这意味着您编写的大多数命令和脚本都可以在任一 shell 中运行,无需修改。 Zsh 构建在 Bash 之上,因此它包含所有相同的基本命令和功能。

然而,语法上存在非常微小的差异,您需要识别和调整。

2. 命令替换一致性

命令替换是将一个命令的输出嵌入到另一个命令的过程。 两个 shell 之间是一致的。

 result=$(ls)  

在 Bash 和 Zsh 中,您可以使用 $(command) 语法将命令的输出替换为变量。 这允许在两个 shell 之间轻松移植脚本。

3. 脚本调试选项

Bash 和 Zsh 都使用 -x 标志进行脚本调试。 当您使用此标志运行脚本时,它会在运行之前显示每个命令。 这可以帮助您识别脚本中的问题。

 # Debugging a script in both Bash and Zsh
#!/bin/bash -x

echo "Debugging Bash script"

在此 Bash 脚本中,-x 标志启用调试。 您可以在 Zsh 中使用类似的方法; 只需将 bash 替换为 zsh 即可。

在 Zsh 和 Bash 之间进行选择的注意事项

  • 兼容性和可移植性:Bash 是许多基于 Unix 的系统上的默认 shell。 这使其成为跨平台脚本编写的更安全选择。 如果您需要脚本无需修改即可在各种系统上运行,Bash 是更好的选择。
  • 脚本复杂性和高级功能:Zsh 提供了高级功能,例如关联数组、扩展的通配模式和高级参数扩展。 这简化了复杂的脚本编写任务。 如果您的脚本需要高级字符串操作或数据结构,Zsh 是更好的选择。
  • 社区和插件生态系统:Bash 和 Zsh 都有活跃的社区,但 Zsh 拥有更强大的社区和广泛的插件和主题生态系统。 如果您重视定制,Zsh 充满活力的社区和插件支持可能是一个显着的优势。
  • 易于学习:如果您不熟悉 shell 脚本,Bash 是一个更容易理解的起点。 它为初学者提供了大量的文档和资源。 这使得学习 shell 脚本的基础知识变得更加容易。

使用 Shell 脚本自动执行任务

了解如何使用 shell 脚本自动执行任务非常重要。 您可以自动执行重复性任务并节省大量时间。

您还可以使用这些脚本来管理用户帐户、监控系统资源、备份数据以及执行日常维护。 如果仔细编写,它们还可以减少人为错误的可能性。