【问题标题】:bash script to process stdin in chunks using dd and redirections使用 dd 和重定向分块处理标准输入的 bash 脚本
【发布时间】:2021-02-24 20:37:08
【问题描述】:

我遇到了一个旧的 bash 脚本,它从标准输入中拆分数据。
当以seq 1234 | ./test_dd_a.sh 运行时,将创建文件 temp.1 到 temp.5。随着它的进展,它显示:

processing part 1
...
processing part 5
processing part 6
extraneous temp.6 will be deleted...

代码如下:

i=1
while true
do
    {
        echo "processing part $i" 1>&2
        dd bs=1k count=1 of="temp.$i" 2>&3
    } 3>&1 | grep -q '^0+0 ' && {
        echo "extraneous temp.$i will be deleted..."
        rm "temp.$i"
        break
    }
    i=`expr $i + 1`
done

我想将其用作将数据从标准输入复制到标准输出的脚本的基础,类似于下面的代码。但是,当以相同方式运行时,它还不会向标准输出提供任何输出,但它会显示进度并在预期时停止。

i=1
while true
do
    {
        echo "processing part $i" 1>&2
        dd bs=1k count=1  2>&3
    } 3>&1 | grep -q '^0+0 ' && {
        break
    }
    i=`expr $i + 1`
done

我希望以最小的更改来完成上述工作,并相信可以通过对重定向进行一些额外的修改来完成。 假设 pv、split 或类似命令不可用。

【问题讨论】:

  • 仅供参考,i=$(expr $i + 1)i=$((i+1)) 相比运行速度要慢得多,并且在便携性上也没有明显提高(因为$(( )) 保证内置于所有符合 POSIX 的外壳中,因为原始发布POSIX.2 在 1992 年)。
  • 顺便说一句,如果第一个 scriptlet 只是查看 dd 刚刚编写的部分是否为空,而不是尝试解析其标准错误,那么第一个 scriptlet 对未记录行为的变化就不那么敏感了。
  • 另外,您将此标记为bash;这是否意味着仅 bash 的扩展是可以接受的?
  • (符合上述声明之一:dd 的 stderr 消息受书面保证的约束,但仅限于 POSIX 区域设置)。
  • 顺便说一句,请注意我的答案中的0[+]0 - 不是[+] 而不是只是裸露的+,字符串00 匹配,因为+ 是正则表达式中的修饰符语法。

标签: bash split io-redirection dd


【解决方案1】:
#!/usr/bin/env bash
i=1
while :; do
  echo "processing part $i" 1>&2
  if { LC_ALL=POSIX dd bs=1k count=1 2>&3 >&4; } 3>&1 | grep -qe '^0[+]0 '; then
    break
  fi
  i=$(( i + 1 ))
done 4>&1

【讨论】:

  • 它对我不起作用。没有任何东西进入标准输出。
  • @fundamental,查看当前版本的代码在ideone.com/nZhohd的在线解释器中成功运行
  • 不错的一个!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 2014-03-28
相关资源
最近更新 更多