代码之家  ›  专栏  ›  技术社区  ›  Seff

不使用tee将stderr复制到stdout

  •  0
  • Seff  · 技术社区  · 4 年前

    我知道有很多类似的问题。但是,没有一个场景能满足我的要求。

    mysql-backup.sh 1> >(logger -it DB_BACKUP) 2> >(push-to-slack.sh)

    这样,备份过程中的任何错误都会立即通知我们。并且stdout保存在syslog中,但是系统日志中缺少stderr。

    简而言之,我需要在syslog中使用stdout+stderr(带有日期、PID等)并将stderr管道(或重定向)到 push-to-slack.sh

    0 回复  |  直到 4 年前
        1
  •  2
  •   John1024 David C. Rankin    4 年前

    push-to-slack.sh 同时将stderr和stdout发送到 logger :

    { mysql-backup.sh 2>&1 1>&3 | tee >(push-to-slack.sh); } 3>&1 | logger -it DB_BACKUP
    

    让我们创建一个同时生成stdout和stderr的函数:

    $ fn() { echo out; echo err>&2; }
    

    $ { fn  2>&1 1>&3 | tee err_only; } 3>&1 | cat >both
    $ cat err_only 
    err
    $ cat both
    out
    err
    

    err_only both 俘获了斯特杜特和斯特德尔。

    (挑剔者注意:是的,我知道 cat 上面的“无用”,但我保持命令与OP需要的命令平行。)

    如果你真的不能用 tee

    { fn  2>&1 1>&3 | (while read -r line; do echo "$line" >&3; echo "$line"; done >err_only); } 3>&1 | cat >both
    

    { fn  2>&1 1>&3 | awk '{print>"err"} 1'; } 3>&1 | cat >both