Bash:如何清理日志处理的ssh / bash输出行? [英] Bash: how to cleanly log processed lines of ssh/ bash output?

查看:168
本文介绍了Bash:如何清理日志处理的ssh / bash输出行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个带有tee和grep的linux bash脚本,用于记录和记录我在各种ssh会话中执行的操作。它有效,但记录的行有时混合在一起,并且充满了控制字符。如何正确地避免控制和其他字符在原始会话中不可见,并分别记录每一行?



我正在学习bash和linux界面,所以任何其他建议来改进脚本都是非常受欢迎的!



这是我的脚本(用作ssh命令的包装器):

 #! / bin / bash 
logfile =〜/ logs / ssh.log
desc =sshlog $ {@}
tab =\t
format_line(){
,而IFS =读-r行; do
echo -e$(date +%Y-%m-%d%H:%M:%S%z)$ {tab} $ {desc} $ {tab} $ {line}
done
}
echo[START]| format_line>> $ {logfile}
#grep用于过滤出命令行输出,同时保留命令
ssh$ @| tee>(grep -e'\ @。* \:。* \ $'--color = never --line-buffered | format_line>> $ {logfile})
echo END]| format_line>> $ {logfile}

这里是日志文件中出现乱码输出的屏幕截图:





有关解决方案的说明: Tiago的答案非常适合打印非打印字符。不幸的是,我只是意识到,这个混乱是由后空间引起的,并且使用上下键来完成命令。也就是说,人物一旦出现就被管道化到grep,而不是逐行。我将不得不在中询问另一个问题



更新:找出了一种方法,(几乎总是)处理上/下完成,退格完成和控制字符。

您可以删除这些字符:



perl -lpe's / [^ [:print:]] // g'



未过滤:

($ i = 0; $ i <= 255; $ i ++){print chr($ i);}'$($ i $) |猫-A
^ @ ^ A ^ B ^ C ^ D ^ E ^ F ^ G ^ H ^ I $
^ K ^ L ^ M ^ N ^ O ^ P ^ Q ^ R ^ S ^ T ^ U ^ V ^ W ^ X ^ Y ^ Z ^ [^ \ ^] ^^^ _!#$%&'()* +, - 。/ 0123456789:;& ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ [\] ^ _`ABCDEFGHIJKLMNOPQRSTUVWXYZ {|}〜^ M - ^ @ ^ M- AM- ^ ^ BM-^ CM-DM-EM-^ ^ ^ FM-GM-HM-^ ^ ^ IM- JM- ^ ^ KM-LM- ^ ^ MM-NM-^ ^ OM-PM-^ ^ QM- RM-^ ^ SM- ^ TM- ^ UM-VM-^ ^ WM-^ XM-^ YM-ZM- (M-M-M-M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M * M- + M-中,M - M-.M- / M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-; M-< M- = M - > M- M- @ M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM -UM-VM-WM-XM-YM-ZM-[M-\M-] M- ^ M-_M-`M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM -kM-LM-MM-介于100nM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-{M- | M-} M-〜M- ^?

已过滤:

 code> perl -e'for($ i = 0; $ i< = 255; $ i ++){print chr($ i);}'| perl -lpe's / [^ [:print:]] // g'| cat -A 
$
!#$%&'()* +, - 。/ 0123456789:;&#160; 〜$

说明:


  1. 我正在打印整个ASCII表:



    perl -e'for($ i = 0; $我


  2. 我正在识别不可打印的字符:



    cat -A


  3. 我正在过滤不可打印的字符:



    perl -lpe's / [^ [:print:]] // g'


编辑:在我看来,您需要删除ANSI颜色字符:



示例:

  perl -MTerm :: ANSIColor -e'print color(yellow on_magenta,yellow on_magenta),\\\
'| sed -rs / \x1B\ [([0-9] {1,2} 0-9] {1,2})?)?[m | K] // g| perl -lpe's / [^ [:print:]] // g'

适应您的代码:

  format_line(){
而IFS =读-r行; do
line = $(sed -rs / \x1B\ [([0-9] {1,2}(; [0-9] {1,2})? | k] // g<$$ line)
line = $(perl -lpe's / [^ [:print:]] // g'<< $ line)
echo -e$(date +%Y-%m-%d%H:%M:%S%z)$ {tab} $ {desc} $ {tab} $ {line}
done
}

我还编辑了你的 grep 命令:

  ssh$ @| tee>(grep -Po'(?<= \ $)。*'--color = never --line-buffered | format_line>> $ {logfile})

下面的测试输出:

  2014-06-26 10:11:10 +0100 sshlog tiago @ localhost [START] 
2014-06-26 10:11:15 +0100 sshlog tiago @ localhost whoami
2014-06-26 10:11:16 +0100 sshlog tiago @ localhost exit
2014-06-26 10:11:16 +0100 sshlog tiago @ localhost [END]


I wrote a linux bash script with tee and grep to log and timestamp the actions I take in my various ssh sessions. It works, but the logged lines are mixed together sometimes and are full of control characters. How can I properly escape control and other characters not visible in the original sessions and log each line separately?

I am learning bash and the linux interface, so any other suggestions to improve the script would be extremely welcome!

Here is my script (used as a wrapper for the ssh command):

#! /bin/bash
logfile=~/logs/ssh.log
desc="sshlog ${@}"
tab="\t"
format_line() {
    while IFS= read -r line; do
        echo -e "$(date +"%Y-%m-%d %H:%M:%S %z")${tab}${desc}${tab}${line}"
    done
}
echo "[START]" | format_line >> ${logfile}
# grep is used to filter out command line output while keeping commands
ssh "$@" | tee >(grep -e '\@.*\:.*\$' --color=never --line-buffered | format_line >> ${logfile})
echo "[END]" | format_line >> ${logfile}

And here is a screenshot of the jarbled output in the log file:

A note on the solution: Tiago's answer took care of the nonprinting characters very well. Unfortunately, I just realized that the jumbling is being caused by backspaces and using the up and down keys for command completion. That is, the characters are being piped to grep as soon as they appear, and not line-by-line. I will have to ask about this in another question.

Update: I figured out a way to (almost always) handle up/down completion, backspace completion, and control characters.

解决方案

You can remove those characters with:

perl -lpe 's/[^[:print:]]//g'

Not filtered:

perl -e 'for($i=0; $i<=255; $i++){print chr($i);}' | cat -A
^@^A^B^C^D^E^F^G^H^I$
^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\M-^]M-^^M-^_M- M-!M-"M-#M-$M-%M-&M-'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-<M-=M->M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?

Filtered:

perl -e 'for($i=0; $i<=255; $i++){print chr($i);}' | perl -lpe 's/[^[:print:]]//g'  | cat -A
$
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~$

Explanation:

  1. I am printing the whole ASCII table with:

    perl -e 'for($i=0; $i<=255; $i++){print chr($i);}'

  2. I am identifying non printable chars with:

    cat -A

  3. I am filtering non printable chars with:

    perl -lpe 's/[^[:print:]]//g'

Edit: It seems to me that you need to remove ANSI color chars:

Example:

 perl -MTerm::ANSIColor -e 'print colored("yellow on_magenta","yellow on_magenta"),"\n"'| sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | perl -lpe 's/[^[:print:]]//g'

Adapting to your code:

format_line() {
    while IFS= read -r line; do
        line=$(sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" <<< "$line")
        line=$(perl -lpe 's/[^[:print:]]//g' <<< "$line")
        echo -e "$(date +"%Y-%m-%d %H:%M:%S %z")${tab}${desc}${tab}${line}"
    done
}

I also edited your grep command:

ssh "$@" | tee >(grep -Po '(?<=\$).*' --color=never --line-buffered | format_line >> ${logfile})

Below the output of my test:

2014-06-26 10:11:10 +0100   sshlog tiago@localhost  [START]
2014-06-26 10:11:15 +0100   sshlog tiago@localhost  whoami
2014-06-26 10:11:16 +0100   sshlog tiago@localhost  exit
2014-06-26 10:11:16 +0100   sshlog tiago@localhost  [END]

这篇关于Bash:如何清理日志处理的ssh / bash输出行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆