由于 和 都ksh
基于bash
许多sh
Korn Shell 脚本 (ksh),一旦 shebang 和文件扩展名发生更改,它们将简单地作为 Bourne-again Shell 脚本 (bash) 运行,
你打电话$ bash script.bash
而不是$ ksh script.ksh
.
我有一个基本脚本来替换名为“files”的目录中出现的任何 ksh 并更改脚本的文件扩展名。
#!/bin/bash/
#replace instances
find ./files -type f - exec sed -i.bak "s/ksh/bash/g" {} \;
#Change extensions
for f in ./files/*.ksh;
do mv "$f" "./files/""$(basename "$f" .ksh).bash"
done
#Clean up
rm ./files/*.bak
该脚本可以工作并执行上述操作,但是它是否足以将任何 ksh 脚本转换为 bash,或者是否存在我没有考虑到的条件?
答案1
该脚本实际上并没有做任何有用的事情。如果您显式使用 bash 运行,则扩展名无关紧要,并且 shebang 行将被忽略。如果您只运行以下命令,您可以获得与脚本完全相同的结果:
bash script.ksh
问题在于语法上的差异。这就是你需要解决的问题否则,只需使用 bash 运行脚本即可完成。
答案2
bash
仅实现了 的功能的子集ksh93
。虽然它实现了 的大部分功能ksh88
,但对于其中一些功能,它的做法有所不同,并且并非所有功能都默认启用。
例如,bash
非交互时不会扩展 中的别名,默认情况下不启用 ksh 扩展 glob,bash
没有print
内置函数,无法使用 定义数组set -A
,协同进程的调用和使用方式不同......
因此,除非这些 ksh 脚本非常简单并且基本上与 POSIX sh 兼容(命令子集的明确定义子集bash
和各种ksh
实现语法),否则它们很可能无法在bash
.
现在,自 2000 年以来,ksh93
它是开源的,并且在大多数操作系统上免费提供(并且大部分向后兼容ksh88
)。对于ksh88
脚本pdksh
和现代衍生品来说mksh
通常也足够了。
它们通常都比 高效得多bash
,所以我不明白为什么您希望让这些脚本由它们bash
而不是它们最初编写的解释器来解释。
Evenzsh
会是一个更好的选择,bash
因为它具有 ksh 模拟模式。
答案3
bash
并且ksh
确实共享语法的很大一部分,因此许多脚本都可以在两者中使用。但是,有些功能ksh
不bash
支持(例如常用表达),任何使用这些功能的脚本都可能出现错误。您的脚本是否简单并不重要 - 正则表达式通常用于简单的if
条件。
简单的脚本确实无法为您解决这些问题。重写正则表达式并不是一项容易自动化的任务。你什么能自动执行是运行环境中的所有脚本chroot
并查看是否bash
抱怨任何语法错误。不过,您不能 100% 确定通过这种方式检测到所有问题,有些问题可能仍然隐藏(语法可能有效,但在bash
和中含义不同ksh
)。
答案4
更严格的方法是运行checkbashisms
检查您的脚本是否确实sh
符合要求。两者都bash
能够ksh
很好地运行这样的脚本。但同样,如果出现任何问题,您将必须手动修复脚本。