我希望从 bash 切换到 zsh,但担心 bash 脚本的兼容性。
所有 bash 脚本/函数都与 zsh 兼容吗?因此,如果这是真的,zsh 是否只是 bash 的增强?
答案1
如果您的脚本以该行开头,#!/bin/bash
即使您的默认 shell 是 zsh,它们仍将使用 bash 运行。
我发现 zsh 的语法非常接近 bash 的语法,并且我没有注意是否确实存在一些不兼容性。 6 年前,我从 bash 无缝切换到 zsh。
答案2
如果您将 Zsh 置于正确的模拟模式(emulate sh
或emulate ksh
),则 Zsh 可以运行大多数 Bourne、POSIX 或 ksh88 脚本。它不支持 bash 或 ksh93 的所有功能。 Zsh 具有 bash 的大部分功能,但在许多情况下具有不同的语法。
您交互使用的 shell 与您拥有的任何脚本无关。运行脚本的 shell 是第一行中指示的 shell,即舍邦线。例如,如果脚本以 开头#!/bin/bash
,则它将由 bash 执行。
如果您自定义了 bash,您将无法将其重命名.bashrc
为.zshrc
.有些东西是可以共享的,例如别名和函数,只要你坚持两个 shell 之间的交集(交集接近 ksh88 和PDKSH)。其他的东西,比如提示设置、完成功能和大多数选项,都需要完全重写。
.bashrc
如果您正在编写一个片段供人们从他们的或中获取.zshrc
,并且您不想维护两个版本,请坚持使用 bash 和 zsh 功能的公共子集,其中包括 bash 的大部分编程功能。将整个代码放在函数中,并将以下行放在每个函数的顶部:
if [ -n "$ZSH_VERSION" ]; then emulate -L ksh; fi
您可以使用emulate sh
而不是emulate ksh
更接近纯 sh 语法,这正是您所需要的.profile
。
如果一个函数调用另一个函数,另一个函数会继承模拟设置,因此您不需要将此行放在内部函数中,只需放在最终用户调用的函数中即可。
答案3
如果 shebang 是#!/bin/bash
并且您启动脚本,因为./script
脚本将由 bash 执行。这里绝对没有问题。
但是,如果您执行zsh ./script
或将其源. ./script
到正在运行的 zsh 实例,则 bash 和 zsh 的语法不匹配是很常见的。
例如,zsh
默认情况下不拆分参数扩展,bash
有内置帮助,zsh 中没有read -p prompt
(语法非常不同 read cmd\?prompt
,zsh 中数组从 1(而不是 0)开始,command
zsh 中仅搜索外部命令,或者${foo^}
zsh 中没有(简单)相当于(仅大写第一个字符),这是一个(大部分)的长列表。相似之处和一些差异。
在某些情况下,zsh
可能会被告知模拟其他 shell。在某些情况下,没有可移植到两个 shell 的通用语法(不使用别名或函数来模拟可移植解决方案)。
但是,zsh
它有许多(很多)扩展,可以更轻松地进行交互工作。这既是转变的一个很好的理由,也是一个问题:
- 很高兴能够看到按选项卡的命令语法选项。
- zsh 的另一个主要好处是在输入错误时进行纠错。 zsh 不仅会显示错误:未找到命令,还会尝试解释您尝试输入的内容。 zsh 会接受此输入作为有效命令。
- 另外,zsh还有很多修饰语到允许大量解决方案的扩展。就像:仅列出文件:(
ls *(.)
这对于其他 shell 来说很困难)。即使当看得足够深入时,答案在 zsh (print -rl -- *(/)
)中也变得复杂。 - 接受带有浮点数的数学(有一些注意事项)。
- Con zsh:
- Bash 是许多系统中的默认 shell。
- 许多 zsh 选项并不能直接帮助编写 bash 兼容的脚本。
- 尝试同时学习两个 shell 甚至可能成为一个大问题。
最终,这是你的选择,而且,我总是喜欢有更多的选择。
答案4
Bash 和 Zsh 是两种不同的解释器,在语言语法方面有各自的特点。
如果您需要 Bash 兼容性来进行交互式调试,您始终可以使用两者。设置 Bash 默认值并运行exec zsh
到 Z Shell,然后exec bash
返回 Bash。
如果您希望 Zsh 作为默认 shell,只需反转即可。
echo $SHELL
当对默认 shell 和echo $0
当前实例 shell 有疑问时运行。- 从 zsh调用
bash ./script
会为脚本生成一个 bash 子 shell,这可能是需要的,也可能是不需要的。