基于返回值而不是退出代码构建管道的优雅方法?

Eva*_*oll 8 shell debian apt shell-script exit-status

当状态码无用时,有没有办法根据stdout的输出构造一个管道?

我希望答案不是针对用例,而是针对 shell 脚本范围内的问题。我想要做的是通过根据国家和语言代码猜测名称来找到存储库中可用的最具体的包。

以这个为例,

  • $PACKAGE1=hunspell-en-zz
  • $PACKAGE2=hunspell-en

第一种猜测更合适,但它可能不存在。在这种情况下,我想回到hunspell-en$PACKAGE2),因为第一个选项hunspell-en-zz$PACKAGE1)也不会存在。

apt-cache 管道

apt-cache只要命令能够运行(来自 的文档apt-cache),该命令就会返回成功(由 shell 定义为退出代码零)

apt-cache 在正常操作时返回零,在错误时返回十进制 100。

这使得在管道中使用命令变得更加困难。通常,我希望包搜索等效于 404 会导致错误(就像curl或会发生的那样wget)。我想搜索以查看包是否存在,如果不存在则回退到另一个包

这不返回任何内容,因为第一个命令返回成功(因此||永远不会运行中的 rhs )

apt-cache search hunspell-en-zz || apt-cache search hunspell-en
Run Code Online (Sandbox Code Playgroud)

apt-cache search 有两个论点

这不返回任何内容,因为apt-cacheAND 其参数,

apt-cache search hunspell-en-zz hunspell-en
Run Code Online (Sandbox Code Playgroud)

从文档 apt-cache

可以使用单独的参数来指定多个搜索模式,这些模式是和'ed 在一起的。

因此,由于这些参数之一显然不存在,因此不会返回任何内容。

问题

处理诸如apt-cache返回代码对任务无用的约定的 shell 习语是什么?成功仅取决于 STDOUT 上是否存在输出?

相似

  • 当没有找到任何东西时,使查找失败

    他们都源于同一个问题。那里提到的选择的答案find -z很遗憾在这里不适用,并且是特定于用例的。没有提到不使用空终止的习惯用法或构建管道(不是 上的选项apt-cache

roa*_*ima 5

创建一个接受命令并返回 true 的函数,如果它有一些输出。

r() { local x=$("$@"); [ -n "$x" ] && echo "$x"; }

( ( r echo -n ) || echo 'nada' ) | cat      # Prints 'nada'
( ( r echo -n foo ) || echo 'nada' ) | cat  # Prints 'foo'
Run Code Online (Sandbox Code Playgroud)

所以对于这个用例,它会像这样工作,

r apt-cache search hunspell-en-zz || r apt-cache search hunspell-en
Run Code Online (Sandbox Code Playgroud)