我有一个脚本,它在后台运行大约 10 个其他脚本,不断生成新的输出。我希望保持初始脚本运行,并且能够简单地输入它以过滤实时显示在终端上的所有输出。
为了简单起见,假设每个 for 循环都代表我的后台脚本之一(顺便说一句,输出包含颜色代码。):
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done &
for i in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $i"
sleep 1
done &
我的第一个想法是将后台脚本的所有输出重定向到一个文件中,然后使用命令read
获取搜索查询并将其传递给grep
如下所示:
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done >> ./output.txt 2>&1 &
for j in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $j"
sleep 1
done >> ./output.txt 2>&1 &
while true ; do
read -p "Search: " query
clear
cat ./output.txt | grep "$query"
done
但这有几个问题。
更新问题:文件更改时输出不会更新output.txt
。所以你必须反复再次搜索才能得到最新的结果。
颜色代码问题:如果我搜索3
它将打印所有行,因为颜色代码包含3
.我当然可以完全过滤掉颜色,如下所示:cat ./output.txt | sed 's/\x1b\[[0-9;]*m//g' | grep "$query"
,但我不想在最终输出中丢失颜色,所以这并不容易。
输入消失问题:即使我在按回车键进行搜索后设法实时打印新的输出,用户也无法正确键入(或查看,更准确地说)他/她的下一个搜索。我希望用户输入的过滤文本始终可见。
有什么想法可以实现这一点吗?
答案1
less -R
您可以使用查看less
器
- 使用选项查看 ANSI 颜色
-R
- 向前搜索
pattern
with/pattern
向后搜索
pattern
with?pattern
使用arrow键 和PgUp、PgDn、Home、进行导航End。
- 请注意,当您按下该键时,您的缓冲区已更新End:-)
- 颜色代码问题已解决。
- 输入并没有消失。
使用以下脚本进行编写,
#!/bin/bash
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done >> output.txt 2>&1 &
for j in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $j"
sleep 1
done >> output.txt 2>&1 &
使用此命令行进行读取/检查,
less -R output.txt
带有fifo
,tail
和 的Shell 脚本grep
简单less
命令的替代方案是以下小 shell 脚本。它假设您可以在终端窗口中滚动足够多的内容来查看旧的输出。如果缓冲区不够大,可以增加缓冲区。我的“.bashrc”中有以下几行,我认为它们为此目的做了您想要的事情,
HISTFILESIZE=1000000
HISTSIZE=10000
用于过滤和检查的 Shellscript,
#!/bin/bash
# this function is called when Ctrl-C is sent ##########################
inversvid="\0033[7m"
resetvid="\0033[0m"
function trap_ctrlc ()
{
# perform cleanup here
echo " Press <Enter> to continue with another query or"
echo -en "$inversvid"
read -s -n1 -t5 -p " <x> to exit " ans
echo -en "$resetvid"
if [ "$ans" == "x" ]
then
# exit shell script
# if omitted, shell script will continue execution
echo ""
exit
else
echo ""
fi
}
##### main #############################################################
# initialise trap to call trap_ctrlc function
# when signal 2 (SIGINT) is received
trap "trap_ctrlc" 2
echo "Scroll the terminal window (maybe inscrease the buffer to store enough lines)
Interrupt viewing the filtered output with <ctrl c>"
if [ "$1" == "" ]
then
read -p "Search: " query
else
query="$@"
fi
# create fifo
mkfifo fifo
# run a loop for queries and filtered output
while true ; do
if [ "$query" == "" ]
then
read -p "New search: " query
fi
# mkfifo fifo
clear
tail -n 10000 -f output.txt > fifo &
grep --color -E "$query" fifo
sleep 0.1
query=""
done
请注意,此 shellscript 还将看到 ANSI 转义序列,因此,例如,如果您想过滤0
,您将看到所有行(因为重置序列中有一个零)。您可以使用扩展正则表达式(其中-E
的选项grep
可以指定您要搜索的内容,例如\ .?0
或0$
.
(这不是问题less -R
)。