如何在不了解 shell 的情况下了解特定代码属于哪个 shell?

如何在不了解 shell 的情况下了解特定代码属于哪个 shell?

我明白这段代码是针对bashshell 的

for f in $file.docked.[0-9][0-9][0-9]
do
  mv $f $f.pdb
done

这段代码是针对tcshshell 的

foreach f ( file.docked.[0-9][0-9][0-9] )
  mv $f $f.pdb
end

这是我在阅读参考文献后明白的。作为一名学习者,我认为这两个代码都可以在bash.有没有一种方法可以在不完全了解不同 shell 的情况下找出特定代码将在哪个 shell 中运行。扩展是否有一种方法可以使代码在所有 shell 上运行,而与编写它的 Linux shell 类型无关?

答案1

for f in $file.docked.[0-9][0-9][0-9]
do
mv $f $f.pdb
done

csh在、tcsh和 Bourne 系列的所有 shell(ash、bash、zsh、ksh、zsh、mksh、yash...)中是语法上有效的代码,但zsh它最有可能做一些有用的事情。

如果该代码的目的是向当前目录中以shell 变量的内容开头并以 3 个 ASCII 十进制数字结尾的.pdb文件名添加后缀,则在 中,您需要:$file.docked.bash

shopt -s failglob
for f in "$file".docked.[0123456789][0123456789][0123456789]
do
mv -- "$f" "$f.pdb"
done

--无论外壳如何,都需要)如bash

  • 就像在 Korn shell 中一样,您需要引用参数扩展,否则它们会经历 split+glob
  • [0-9]通常匹配比 0123456789 更多的字符,其列表因区域设置和系统而异。您只需要[0123456789]匹配bash0123456789(不,最新版本的选项globasciiranges没有帮助)。
  • 当它们不匹配时,glob 不会展开,因此如果没有匹配的文件,您将在循环中获得$f包含的一次传递。 (获得与 csh 或 zsh 类似的行为)或(从 复制的选项)解决该问题。contents-of-file-variable.docked.[0-9][0-9][0-9]failglobnullglobzsh
foreach f ( file.docked.[0-9][0-9][0-9] )
  mv $f $f.pdb
end

看起来确实像csh语法,但这又是zsh语法。应该(t)csh是:

foreach f ( file.docked.[0-9][0-9][0-9] )
  mv -- $f:q $f:q.pdb
end

(尽管在该特定情况下,:q与其他示例相反,s 并不是严格必需的,但保证文件名不包含 SPC、TAB、LF 或通配符)。

编写有效的代码并且用完全不同的语言做同样的事情是非常棘手的。一般称为多语言编码。这Code Golf stackex姐妹网站有一个专门的部分。但这不是您通常想做的事情。

这个网站上的这个例子作为实现这一目标所需的长度的示例。

相关内容