在Zsh中组合文件测试

在Zsh中组合文件测试,zsh,Zsh,zsh中最优雅的测试方法是什么,一个文件是否是可读的常规文件 我知道我可以做类似的事情 if [[ -r "$name" && -f "$name" ]] ... if ls ${name}(R.) >/dev/null 2>&1 ... 但它需要重复$name两次。我知道我们不能组合条件-rf$name,但也许可以使用zsh中的其他功能 顺便说一下,我也考虑过 if [[ -r "$name" && -f "$name" ]] ...

zsh中最优雅的测试方法是什么,一个文件是否是可读的常规文件

我知道我可以做类似的事情

if [[ -r "$name" && -f "$name" ]]
...
if ls ${name}(R.) >/dev/null 2>&1
...
但它需要重复$name两次。我知道我们不能组合条件-rf$name,但也许可以使用zsh中的其他功能

顺便说一下,我也考虑过

if [[ -r "$name" && -f "$name" ]]
...
if ls ${name}(R.) >/dev/null 2>&1
...
但是在这种情况下,当$name不符合标准时,shell会抱怨找不到匹配项。在这里设置NULL_GLOB也没有帮助,因为它只会用一个空字符串替换模式,并且表达式始终为true。

在非常新的zsh版本中,适用于5.0.7,但不适用于5.0.5,您可以这样做

setopt EXTENDED_GLOB

if [[ -n $name(#qNR.) ]]
...
$nameqNR。匹配名为$name且可读且常规的文件。。N为此匹配启用NULL_GLOB。也就是说,如果没有与模式匹配的文件,则不会产生错误,但会从参数列表中删除-n检查匹配事实上是否为非空。需要扩展_GLOB来启用q。。。扩展globbing的类型,这是必需的,因为括号在条件表达式[…]中通常有不同的含义

尽管如此,尽管确实有可能只写一次使用$name的东西,但我还是建议不要这样做。它比原来的解决方案更复杂,因此更难理解,也就是说,需要为阅读它的下一个家伙着想——你未来的自己最多半年后算作下一个家伙。至少这个解决方案只能在zsh上运行,而且只能在新版本上运行,而原来的解决方案在bash上运行时不会改变。

在非常新的zsh版本中,可以在5.0.7上运行,但不能在5.0.5上运行

setopt EXTENDED_GLOB

if [[ -n $name(#qNR.) ]]
...
$nameqNR。匹配名为$name且可读且常规的文件。。N为此匹配启用NULL_GLOB。也就是说,如果没有与模式匹配的文件,则不会产生错误,但会从参数列表中删除-n检查匹配事实上是否为非空。需要扩展_GLOB来启用q。。。扩展globbing的类型,这是必需的,因为括号在条件表达式[…]中通常有不同的含义


尽管如此,尽管确实有可能只写一次使用$name的东西,但我还是建议不要这样做。它比原来的解决方案更复杂,因此更难理解,也就是说,需要为阅读它的下一个家伙着想——你未来的自己最多半年后算作下一个家伙。至少这个解决方案只能在zsh上运行,而且只能在新版本上运行,而原来的解决方案在bash上运行时不会改变。

如您所述,制作小型shell函数怎么样

原始测试{ setopt localoptions no_ksharrays 本地则=1美元;班次 局部f=${@[-1]}t= 本地-i ret=0 集合-${@[1,-2]} 对于${@[@]};do中的t 如果测试$t$f;则 ret=$? 美元 其他的 返回美元? fi 完成 回程网 } 和测试${@[@]}; 或测试原始中断${@[@]}; 例子 name=/dev/null if和-r-c$名称;然后 echo“好的,这是一个可读+字符的特殊文件。” fi >>好的,是。。。 和-r-f~/.zshrc;echo$?>>0 或-r-d~/.zshrc;echo$?>>0 和-r-d~/.zshrc;echo$?>>1. 它可能是`和-rd~/.zshrc`可能的。
我觉得这有点过分了。

如您所述,制作小型shell函数怎么样

原始测试{ setopt localoptions no_ksharrays 本地则=1美元;班次 局部f=${@[-1]}t= 本地-i ret=0 集合-${@[1,-2]} 对于${@[@]};do中的t 如果测试$t$f;则 ret=$? 美元 其他的 返回美元? fi 完成 回程网 } 和测试${@[@]}; 或测试原始中断${@[@]}; 例子 name=/dev/null if和-r-c$名称;然后 echo“好的,这是一个可读+字符的特殊文件。” fi >>好的,是。。。 和-r-f~/.zshrc;echo$?>>0 或-r-d~/.zshrc;echo$?>>0 和-r-d~/.zshrc;echo$?>>1. 它可能是`和-rd~/.zshrc`可能的。
我觉得这有点过分。

我忍不住要问:为什么?第一个示例可读性很好,不太长,而且您已经在使用一个变量,因此意外地给出不同的路径不是问题。这可能是因为我的Perl根源。在非常旧的Perl版本中,也必须以类似的方式编写它,Perl社区对此表示不满,直到引入了快捷方式。在Perl中,您可以像if-r-f$name那样编写它,所以我也希望在zsh中有类似的简单解决方案?第一个示例可读性很好,不太长,而且您已经在使用一个变量,因此意外地给出不同的路径不是问题。这可能是因为我的Perl根源。在非常旧的Perl版本中,也必须以类似的方式编写它,Perl社区对此表示不满,直到引入了快捷方式。在Perl中,您可以将其编写为if-r-f$name,因此我希望在zsh中有类似的简单解决方案 也是。这是一个杀伤力过大的主意,但对于我经常需要这种测试的应用程序来说是个好主意。这是一个杀伤力过大的主意,但对于我经常需要这种测试的应用程序来说是个好主意。