Bash 如何从程序中收集日志和输出,并将它们传递到函数的参数中
我有一个shell脚本,它有一个记录语句的函数Bash 如何从程序中收集日志和输出,并将它们传递到函数的参数中,bash,shell,sh,embedded-linux,Bash,Shell,Sh,Embedded Linux,我有一个shell脚本,它有一个记录语句的函数 #!/bin/sh Log() { echo $1 >> /some/logfile } Log "Test logging works" 这太棒了 接下来,我有一个记录语句的程序,如果我想将其中的日志添加到一个文件中,我可以这样做 SomeProgram >> SomeFile.txt 这也非常有效 但是,如果我想将日志从SomeProgram传递到我的函数Log,同时从同一shell脚本调用SomePro
#!/bin/sh
Log() {
echo $1 >> /some/logfile
}
Log "Test logging works"
这太棒了
接下来,我有一个记录语句的程序,如果我想将其中的日志添加到一个文件中,我可以这样做
SomeProgram >> SomeFile.txt
这也非常有效
但是,如果我想将日志从SomeProgram
传递到我的函数Log
,同时从同一shell脚本调用SomeProgram
,该怎么办。可能吗?以下是我尝试过的一些不起作用的技巧
Log "SomeProgram >> SomeFile.txt"
Log(SomeProgram >> SomeFile.txt)
问题那么,我如何从程序中收集日志并将其传递到函数的参数中呢 环境:
Linux使用
tee
分割输出
Log "$(SomeProgram | tee -a SomeFile.txt)"
说明:
SomeProgram | tee
将stdio输出从SomeProgram
传递到tee
命令
tee-a SomeFile.txt
将输出到stdio,同时-a
添加到SomeFile.txt
Log“$(……”
将捕获括号内命令的stdio,并将结果作为参数传递给Log
函数。您可以编写一个函数来处理标准输入和任何参数:
Log(){
#如果STDIN(0)不是终端,则迭代任何标准输入行
[!-t0]&&while read line;do echo“$line”>>/some/logfile;done
#迭代提供的任何参数
对于arg;执行echo“$arg”>>/some/logfile;完成
}
如果您有一个连续输出文本行的程序,您可以通过管道将该程序的标准输出传输到函数的标准输入,手动输入参数,或者两者兼而有之
SomeProgram|Log
记录“第一行”“第二行”
SomeProgram |记录“附加第1行”和“附加第2行”
查看
manbash
,/^*复合命令
,了解可用于函数的所有语法类型。如果是一次性的,我会编写一个循环
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
不要!这样做会导致
Log()
在任何时候以非交互方式调用脚本时使用stdin。好的脚本在自动化和用于管道时表现良好;他们不坚持键盘输入。记录“$(./SomeProgram)”
这不起作用吗?SomeProgram的输出应该传递给Log。我不确定SomeFile.txt与您尝试执行的操作有什么关系?命令替换将等待SomeProgram完成,然后再传递一个值,这对于正在进行的日志记录是不可取的;执行,否则它将跳过不以换行符结尾的行。惯用的方法是当IFS=read-r line时使用,这样就不会忽略前导和尾随空格。@vintnes我更新了问题描述,将其称为“函数”而不是“方法”。检查stdin是否为tty是一个坏主意。现在,如果用户在管道中运行脚本,它将把所有输入都作为日志消息接收,它将使尝试读取stdin的任何其他命令都无法使用。例如,如果脚本说Log“询问用户名”;read-p'user:'user
,如果stdin不是tty,Log
调用将使用read
的输入。用户可能正试图用echo“bob”|./script
自动回答提示。
SomeProgram | Log --stdin