Bash提示低于输出-背景日志尾


15

我曾经在一家拥有定制外壳程序的公司工作,该外壳程序用于管理在Linux上运行的其中一种产品,并且我希望复制该外壳程序的关键功能。

所有工作都是通过后台进程完成的,日志的输出显示给所有连接的用户。

日志将在外壳的背景中尾部出现,并且提示行将始终完美地位于底部。

例如

Log line 1
Log line 2
Log line 3
![ROOT@PRODUCT51-LIVE]:~/ #

我尝试使用bash进行此操作的方法是在用户.bashrc文件中启动一个分离的尾巴,但是当命令的输出发送到stdout时-它出现在bash提示符下,例如

![ROOT@PRODUCT51-LIVE]:~/ #Log line 1
Log line 2
Log line 3

用户必须按Enter或输入CtrlC干净提示行。

我没有关于如何使提示始终跳到输出底部的想法,并且我认为我使用了错误的术语来在Google上找到任何内容,因为我没有运气-有人知道如何做到这一点用bash?


1
您希望输出立即更新还是在收到新提示时更新?
ahilsend 2013年

立即,因此它与只运行“ tail -f”尽可能相同,但在底部显示提示。
iamacarpet

发生了什么tail -f,当你输入具有输出的显著量的指令时,你的后台进程正在积极地将其输出发送输出和提示和命令的输出,特别是?
暂停,直到另行通知。

在他们的情况下,仅会运行的命令是通过后台进程导致的输出,而不是靠它们自己产生的,因此这不是问题。在这种情况下,一旦我们找到了一种能够达到预期效果的解决方案,我认为这是一个案例,看看在实现与实现的基础上,混合的输出有多糟糕。
iamacarpet

1
然后,我强烈支持使用screen或tmux的建议。输出不会混淆或争夺屏幕空间,您可以调整窗口大小(移动拆分)并独立滚动它们。如果您反对页眉/页脚/状态行“繁重”,则可以进行配置。没有重新发明轮子。
暂停,直到另行通知。

Answers:


1

下面的代码可以满足您的需要,而无需使用tmux或screen或其他程序。将提示保持在底部。将“ / var / log / cron”替换为所需的任何文件:

#!/bin/bash 
L=$(tput lines)
L1=${L}
(( L1-- ))
C=$(tput cols)
tput cup ${L} 0
tail -f /var/log/cron | while read line; do 
  tput sc
  printf "\e[1;${L1}r\e[${L1};${C}f" 
  echo; echo ${line}
  printf "\e[1;${L}r" && tput rc
done

关键是终端的ANSI控制字符。特别是“ \ e [x; y”语句,它设置了一个新的可滚动区域。因此,在读取日志文件的每一行时,窗口的底行将从可滚动区域中排除,插入日志文件中的行,然后将底行添加回去。


谢谢Michael,它的运行效果很不错 =]-我确实偶尔遇到问题,因为在滚动很多日志行时,您正在键入,但是您不能在控制台行上退格所有文本(我当时在测试繁忙的apache日志),但是对于我想使用的日志来说,这应该不是问题。
iamacarpet

@iamacarpet太好了。很高兴为您工作。
Michael Martinez 2013年

11

答案是屏幕或使用了tmux

我将解释如何使用屏幕进行配置

1) apt-get install screen在Ubuntu / Debian或yum install screen RedHat衍生版本。

2) screen -S shell_and_logs

3)然后按Ctrl+ a,然后按S(大写S)。
出现水平屏幕

4)按Ctrl+,a然后按TAB
这将跳到第二个拆分窗口。

5)在此处创建另一个窗口,然后按Ctrl+ a释放键,然后按,将得到命令提示符c

6)您可以按Ctrl+ 调整第二个窗口的大小,a然后键入:resize, 然后Lines:出现。输入要显示的行数。

7)最后,您可以在Windows之间按 Ctrl+,a然后按TAB

见下面的例子


谢谢val0x00ff-我喜欢这个想法,它可以完成工作-但它看起来不像问题系统所提供的体验那么干净。对于没有经验的用户,它不是那么透明-它显然是另一个shell,而不仅仅是感觉您的主shell正在使您保持更新。
iamacarpet

@iamacarpet这tail -F /var/log/messages &是在某些情况发生更改时向您显示消息的另一种方式,例如,发现登录失败或某些服务出现问题时。但是,这并不理想,因为它会使您的交互式外壳混乱。
Valentin Bajrami

是的,这正是我所要的-一种在不搞乱交互式shell的情况下做到这一点的方法-因为这是他们在公司shell上设法做到的-但最好不必从头开始编写shell完成它。
iamacarpet 2013年

1
@iamacarpet有除了一堆其他工具screen,并tmux可以做到这一点-比如一些BSD系统的配套提供了window命令。尽管有选择余地,但由于其灵活性,我建议将此解决方案推荐给自定义外壳程序或其他可用选项。对于最终用户而言,它可能不那么透明,但是他们真的不知道它们之间的区别,并且高级用户/系统管理员将能够使用所提供的额外灵活性screen
voretaq7

@iamacarpet t=$(mktemp); printf '%s\n' 'screen tail -F /var/log/messages' split focus screen > "$t"; screen -S screenname -c "$t"将其放入脚本中,并在每次需要时运行。感谢geirha在#bash @ irc.freenode.org上所做的工作
Valentin Bajrami
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.