我有一个Shell脚本,它具有Log语句功能
#!/bin/sh
Log() {
echo $1 >> /some/logfile
}
Log "Test logging works"
这很好用!
接下来,我有一个用于记录语句的程序,如果我想从那里将日志添加到文件中,我可以这样做
SomeProgram >> SomeFile.txt
这也很棒!
但是,如果我想在同一外壳脚本中调用SomeProgram
时将日志从Log
传递到函数SomeProgram
中,该怎么办。那可能吗?以下是我尝试的一些技巧,这些技巧无效。
Log "SomeProgram >> SomeFile.txt"
Log(SomeProgram >> SomeFile.txt)
问题
那么,如何才能从程序中收集日志并将其不断传递到函数的参数中?
环境:
Linux
答案 0 :(得分:2)
如果是一次性案例,我会写一个循环。
SomeProgram | while IFS= read -r line; do
Log "$line"
done
如果要执行很多操作,可以在Log
中添加第二种模式,在该模式下,它从stdin读取而不是其参数。
Log() {
case $1 in
--stdin)
while IFS= read -r line; do Log -- "$line"; done
return;;
--)
shift;;
esac
echo "$*" >> /some/logfile
done
SomeProgram | Log --stdin
请勿check if stdin is a tty!这样做会导致Log()
在您的脚本被非交互式调用时消耗stdin。好的脚本在自动化并在管道中使用时表现良好。他们不坚持使用键盘输入。
答案 1 :(得分:1)
您可以编写一个函数来处理标准输入以及任何参数:
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
,以了解适用于函数的所有语法类型。
答案 2 :(得分:-1)
使用tee
分割输出
Log "$(SomeProgram | tee -a SomeFile.txt)"
说明:
SomeProgram | tee
将stdio输出从SomeProgram
传递到tee
命令
tee -a SomeFile.txt
将输出到stdio,同时将-a
添加到SomeFile.txt
Log "$(......)"
将捕获括号内命令的标准输入并将结果作为参数传递给Log
函数。