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

Pra*_*r-M 1 bash tcsh

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

for f in $file.docked.[0-9][0-9][0-9]
do
  mv $f $f.pdb
done
Run Code Online (Sandbox Code Playgroud)

这段代码是针对tcshshell的

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

Run Code Online (Sandbox Code Playgroud)

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

Sté*_*las 6

for f in $file.docked.[0-9][0-9][0-9]
do
mv $f $f.pdb
done
Run Code Online (Sandbox Code Playgroud)

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

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

shopt -s failglob
for f in "$file".docked.[0123456789][0123456789][0123456789]
do
mv -- "$f" "$f.pdb"
done
Run Code Online (Sandbox Code Playgroud)

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

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

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

foreach f ( file.docked.[0-9][0-9][0-9] )
  mv -- $f:q $f:q.pdb
end
Run Code Online (Sandbox Code Playgroud)

(尽管在这种特殊情况下,与:q其他示例相反,s 并不是绝对必要的,文件名保证不包含 SPC、TAB、LF 或通配符)。

编写有效的代码并且用完全不同的语言做同样的事情是非常棘手的。它通常被称为多语言编码。该代码高尔夫stackexchange姊妹网站有一个部分。但这不是您通常想做的事情。

请参阅此站点上的此示例作为实现它所需的长度类型的示例。