如何收集程序的日志和输出并将它们传递给函数的参数
How to collect the logs and output from a program and pass them into the parameter of a function
我有一个 shell 脚本,它具有记录语句的功能
#!/bin/sh
Log() {
echo >> /some/logfile
}
Log "Test logging works"
效果很好!
接下来,我有一个记录语句的程序,如果我想将那里的日志添加到文件中,我可以这样做
SomeProgram >> SomeFile.txt
这也很好用!
但是,如果我想在从同一个 shell 脚本调用 SomeProgram
的同时将日志从 SomeProgram
传递到我的函数 Log
中怎么办?那可能吗?以下是我尝试过但没有用的一些技巧。
Log "SomeProgram >> SomeFile.txt"
Log(SomeProgram >> SomeFile.txt)
问题
那么,如何从程序中收集日志并将它们传递到函数的参数中呢?
环境:
Linux
使用tee
拆分输出
Log "$(SomeProgram | tee -a SomeFile.txt)"
解释:
SomeProgram | tee
将 SomeProgram
的 stdio 输出传递给 tee
命令
tee -a SomeFile.txt
会输出到stdio同时-a
加到SomeFile.txt
Log "$(......)"
将捕获括号内命令的 stdio,并将结果作为参数传递给 Log
函数。
您可以编写一个函数来处理标准输入以及任何参数:
Log() {
# if STDIN (0) is not a terminal, iterate over any lines of standard input
[[ ! -t 0 ]] && while read line; do echo "$line" >> /some/logfile; done
# iterate over any arguments provided
for arg; do echo "$arg" >> /some/logfile; done
}
如果您有一个连续输出文本行的程序,您可以通过管道 |
该程序的标准输出到您函数的标准输入,手动输入参数,或两者兼而有之!
SomeProgram | Log
Log "line one" "line two"
SomeProgram | Log "additional line one" "additional line two"
查看 man bash
、/^ *Compound Commands
以了解适用于函数的所有语法类型。
如果是一次性的,我会写一个循环。
SomeProgram | while IFS= read -r line; do
Log "$line"
done
如果你要经常这样做,你可以向 Log
添加第二种模式,它从标准输入而不是它的参数读取。
Log() {
case in
--stdin)
while IFS= read -r line; do Log -- "$line"; done
return;;
--)
shift;;
esac
echo "$*" >> /some/logfile
done
SomeProgram | Log --stdin
不要!这样做会导致 Log()
在您的脚本被调用时消耗标准输入 non-interactively。好的脚本在自动化和在管道中使用时表现良好;他们不坚持键盘输入。
我有一个 shell 脚本,它具有记录语句的功能
#!/bin/sh
Log() {
echo >> /some/logfile
}
Log "Test logging works"
效果很好!
接下来,我有一个记录语句的程序,如果我想将那里的日志添加到文件中,我可以这样做
SomeProgram >> SomeFile.txt
这也很好用!
但是,如果我想在从同一个 shell 脚本调用 SomeProgram
的同时将日志从 SomeProgram
传递到我的函数 Log
中怎么办?那可能吗?以下是我尝试过但没有用的一些技巧。
Log "SomeProgram >> SomeFile.txt"
Log(SomeProgram >> SomeFile.txt)
问题
那么,如何从程序中收集日志并将它们传递到函数的参数中呢?
环境:
Linux
使用tee
拆分输出
Log "$(SomeProgram | tee -a SomeFile.txt)"
解释:
SomeProgram | tee
将 SomeProgram
的 stdio 输出传递给 tee
命令
tee -a SomeFile.txt
会输出到stdio同时-a
加到SomeFile.txt
Log "$(......)"
将捕获括号内命令的 stdio,并将结果作为参数传递给 Log
函数。
您可以编写一个函数来处理标准输入以及任何参数:
Log() {
# if STDIN (0) is not a terminal, iterate over any lines of standard input
[[ ! -t 0 ]] && while read line; do echo "$line" >> /some/logfile; done
# iterate over any arguments provided
for arg; do echo "$arg" >> /some/logfile; done
}
如果您有一个连续输出文本行的程序,您可以通过管道 |
该程序的标准输出到您函数的标准输入,手动输入参数,或两者兼而有之!
SomeProgram | Log
Log "line one" "line two"
SomeProgram | Log "additional line one" "additional line two"
查看 man bash
、/^ *Compound Commands
以了解适用于函数的所有语法类型。
如果是一次性的,我会写一个循环。
SomeProgram | while IFS= read -r line; do
Log "$line"
done
如果你要经常这样做,你可以向 Log
添加第二种模式,它从标准输入而不是它的参数读取。
Log() {
case in
--stdin)
while IFS= read -r line; do Log -- "$line"; done
return;;
--)
shift;;
esac
echo "$*" >> /some/logfile
done
SomeProgram | Log --stdin
不要Log()
在您的脚本被调用时消耗标准输入 non-interactively。好的脚本在自动化和在管道中使用时表现良好;他们不坚持键盘输入。