【问题标题】:Make a bash function fail when on empty使 bash 函数在空时失败
【发布时间】:2022-11-22 01:41:30
【问题描述】:

我想编写一个始终具有非空输出或失败的函数,但我缺少一个命令,该命令读取 stdin 并在非空或失败时将其通过管道传输到 stdout,例如:

example() {
  do_something_interesting_here $1 | cat_or_fails
}

这个想法是,如果给命令 cat_or_fails 一个空输入,它将失败(因此函数失败)或者输入没有任何更改地输出(如 cat)。

但是我找不到任何能够实现该技巧的标准实用程序,或者我不确定如何使用这些工具。

【问题讨论】:

  • 这听起来像是 moreutils 中的东西,但软件推荐请求在这里显然是题外话。
  • ...因此,如果我将其视为主题,我会回答如何在 bash 中实现它没有出于相同目的讨论 3rd 方工具。
  • 我正在考虑一些作为标准工具的聪明技巧,例如使用 grep 与匹配任何非空的东西,例如......感觉就像有一个我没有看到的通用解决方案...
  • 也许 grep . 可以满足您的需求。如果输入是纯空格,则返回非零值,因此可能不是您要查找的内容。
  • 如果您关心简洁性,我会使用 awk 单行代码(我可以详细讨论您不应该这样做——shell 中的简洁性通常是以牺牲正确性为代价的),但是不,没有“通用解决方案” .

标签: bash shell


【解决方案1】:

实现此目的的简单算法简单明了:尝试读取一个字节。如果有效,将该字节写回,然后运行cat。如果失败,则以非零状态退出。


一个非常简单的实现(不尝试处理二进制文件)如下所示:

cat_or_fails() {
  local firstbyte
  IFS= read -r -n 1 firstbyte || return
  printf '%s' "${firstbyte:-$'
'}"
  cat
}

一个稍微不那么简单的实现尝试正确处理二进制文件可能看起来像:

cat_or_fails() {
  local firstbyte
  IFS= read -r -d '' -n 1 firstbyte || return
  if [[ $firstbyte ]]; then
    printf '%s' "$firstbyte"
  else
    printf '
【解决方案2】:

按照 @William Pursell in the comment 的想法,grep 似乎可以使用类似的方法来解决问题:

example() {
  do_something_interesting_here $1 | grep "[[:alnum:]]"
}

如 cmets 中所述,它将消耗任何空行(或与给定的正则表达式不匹配的任何行)。

【讨论】:

    猜你喜欢
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多