用另一个脚本处理 stderr
handle stderr with another script
我有一个脚本(例如 compute.sh)在我的 Ubuntu 16.04 上执行某些操作并且可能以错误结束,比方说:
[compute.sh]
#!/bin/bash
...
MISCELLANEOUS OPERATIONS
...
[if error occours]
echo "Error 55a" >&2;
exit 1;
...
echo "Execution ok";
exit 0;
和另一个处理错误的脚本(例如error_handler.sh)
[error_handler.sh]
error=$(cat)
for i in "$@"
do
case $i in
-u=*|--user=*)
username="${i#*=}"
shift
;;
-t=*|--task=*)
task="${i#*=}"
shift
;;
esac
done
...
SENDS ERROR REPORTING THROUGH AN API LISTENING REMOTELY
...
我想执行 compute.sh,将其 stderr 重定向到 error_handler.sh 以便通知我的 API 系统发生了错误
如果我尝试这个测试:
user@ubuntu: echo "test message" | ./error_handler.sh --user=dude --task="simple task"
我的 error_handler.sh 脚本接受字符串 "test message" 并正确处理它
如何仅将 stderr 输出重定向到我的 error_handler.sh 脚本?
编辑:有时 compute.sh 可能会在没有错误消息的情况下失败(只需执行 exit 1;)我不确定 error=$(cat) 是否是捕获错误消息的正确方法error_handler.sh。还有其他选择吗?
EDIT2:任务可能在 crontab 中执行,所以我需要在同一个命令中执行所有操作
最简单的做法是创建一个命名管道作为两者之间的缓冲区。
mkfifo errors # "errors" is an arbitrary file name
compute.sh 2> errors & # Run in the background
error_handler.sh < errors
作为一行:
mkfifo errors; compute.sh 2> errors & error_handler.sh
现在两个进程 运行 并发,并且 error_handler.sh
可以从 errors
读取,而 compute.sh
可以写入它。缓冲区大小有限,所以 compute.sh
如果满了会自动阻塞。一旦 error_handler.sh
消耗了一些输入,compute.sh
将自动恢复。只要错误不会产生得太快(即比 error_handler.sh
处理它们的速度更快),compute.sh
将 运行 就好像缓冲区是无限的。
如果缓冲区被清空,error_handler.sh
将阻塞直到有更多输入可用,或者直到 compute.sh
通过退出关闭其管道末端。
常规管道语法foo | bar
创建匿名管道(或未命名管道),它只是
的快捷方式
mkfifo tmp
foo > tmp &
bar < tmp
但限制您将一个命令的标准输出连接到另一个命令的标准输入。使用其他文件描述符需要扭曲的重定向。使用命名管道的输入时间稍长,但阅读起来多更清晰。
我有一个脚本(例如 compute.sh)在我的 Ubuntu 16.04 上执行某些操作并且可能以错误结束,比方说:
[compute.sh]
#!/bin/bash
...
MISCELLANEOUS OPERATIONS
...
[if error occours]
echo "Error 55a" >&2;
exit 1;
...
echo "Execution ok";
exit 0;
和另一个处理错误的脚本(例如error_handler.sh)
[error_handler.sh]
error=$(cat)
for i in "$@"
do
case $i in
-u=*|--user=*)
username="${i#*=}"
shift
;;
-t=*|--task=*)
task="${i#*=}"
shift
;;
esac
done
...
SENDS ERROR REPORTING THROUGH AN API LISTENING REMOTELY
...
我想执行 compute.sh,将其 stderr 重定向到 error_handler.sh 以便通知我的 API 系统发生了错误
如果我尝试这个测试:
user@ubuntu: echo "test message" | ./error_handler.sh --user=dude --task="simple task"
我的 error_handler.sh 脚本接受字符串 "test message" 并正确处理它
如何仅将 stderr 输出重定向到我的 error_handler.sh 脚本?
编辑:有时 compute.sh 可能会在没有错误消息的情况下失败(只需执行 exit 1;)我不确定 error=$(cat) 是否是捕获错误消息的正确方法error_handler.sh。还有其他选择吗?
EDIT2:任务可能在 crontab 中执行,所以我需要在同一个命令中执行所有操作
最简单的做法是创建一个命名管道作为两者之间的缓冲区。
mkfifo errors # "errors" is an arbitrary file name
compute.sh 2> errors & # Run in the background
error_handler.sh < errors
作为一行:
mkfifo errors; compute.sh 2> errors & error_handler.sh
现在两个进程 运行 并发,并且 error_handler.sh
可以从 errors
读取,而 compute.sh
可以写入它。缓冲区大小有限,所以 compute.sh
如果满了会自动阻塞。一旦 error_handler.sh
消耗了一些输入,compute.sh
将自动恢复。只要错误不会产生得太快(即比 error_handler.sh
处理它们的速度更快),compute.sh
将 运行 就好像缓冲区是无限的。
如果缓冲区被清空,error_handler.sh
将阻塞直到有更多输入可用,或者直到 compute.sh
通过退出关闭其管道末端。
常规管道语法foo | bar
创建匿名管道(或未命名管道),它只是
mkfifo tmp
foo > tmp &
bar < tmp
但限制您将一个命令的标准输出连接到另一个命令的标准输入。使用其他文件描述符需要扭曲的重定向。使用命名管道的输入时间稍长,但阅读起来多更清晰。