为什么循环读取 /dev/urandom 失败

为什么循环读取 /dev/urandom 失败

外壳脚本

#!/bin/bash

set -euo pipefail

for i in {1..1000}; do
    head -c 10000 /dev/urandom | tr -dc '0-1' | head -0 \
        && echo -n . \
        || { echo -e "\nNum $i, Unknown error!"; break; }
    sleep 0.1
done

描述

  • 唯一的关键命令是
    head -c 10000 /dev/urandom | tr -dc '0-1' | head -0
    
  • 这个脚本在几秒钟后就崩溃了
    .......................................
    Num 40, Unknown error!
    

问题

  • 为什么这个脚本中止?

答案1

首先,要获取进程的退出代码,请使用$?.将您的错误报告替换为:

echo -e "\nNum $i, error: $?"; break; 

这将表明当您的脚本退出时,程序会以代码 141 退出。

这个答案代码 141 表示该进程已被终止SIGPIPE

由于您要求head读取 0 行,因此它可能会在前面的程序将任何内容写入其输出流之前退出,从而导致错误。

解决这个问题的一种方法是稍微延迟最后的头部:

set -euo pipefail

for i in {1..1000}; do
    if head -c 10000 /dev/urandom | tr -dc '0-1' | (sleep 0 && head -0) ; then
    echo -n . 
    else
     echo -e "\nNum $i, error: $?"; break; 
     fi
    sleep 0.1
done

相关内容