在bash中,调用foo
将在stdout上显示该命令的任何输出.
调用foo > output
会将该命令的任何输出重定向到指定的文件(在本例中为'output').
有没有办法将输出重定向到文件并将其显示在stdout上?
这是否可以grep
连续使用?
我的意思是一种tail -f <file>
命令,但grep
在输出上只是为了保留我感兴趣的行.
我已经尝试了,tail -f <file> | grep pattern
但似乎grep
只能执行一次tail
,也就是说永远不会.
我最后在Python中为此编写了一个快速的小脚本,但我想知道是否有一个实用程序可以提供文本,其中每个行前面都有一些文本 - 在我的特定情况下,是一个时间戳.理想情况下,使用方式如下:
cat somefile.txt | prepend-timestamp
Run Code Online (Sandbox Code Playgroud)
(在你回答sed之前,我试过这个:
cat somefile.txt | sed "s/^/`date`/"
Run Code Online (Sandbox Code Playgroud)
但是,这只会在执行sed时评估date命令,因此每行都会错误地添加相同的时间戳.)
我有一个程序(服务器),我正在寻找一种方法(脚本),它将所有stdout
文件重定向(或更好地复制)并为每个条目添加时间戳.
我已经完成了一些研究,我能得到的最远的就是如何将时间戳添加到STDERR重定向.它重定向stdout
但添加的时间戳是脚本完成的时间:
#!/bin/bash
./server | ./predate.sh > log.txt
Run Code Online (Sandbox Code Playgroud)
代码predate.sh
:
#!/bin/bash
while read line ; do
echo "$(date): ${line}"
done
Run Code Online (Sandbox Code Playgroud)
似乎退出程序后刷新服务器输出.(没有重定向它工作正常).此外,如果我尝试predate.sh
在提到的线程中使用给定的示例,它可以完美地工作.我知道在主程序中添加时间戳很容易,但我宁愿避免编辑它的代码.
我正在使用shell-command在emacs缓冲区中运行应用程序的输出.
(shell-command "verbose-app &" "*verbose-app*")
Run Code Online (Sandbox Code Playgroud)
问题是这个命令非常冗长.这么多,emacs缓冲区有时需要几秒钟才能赶上.它与实际输出相差几秒钟.
有什么办法可以通过禁用某些东西加快输出滚动速度吗?像正则表达式匹配或语法高亮?
备查:
详细的应用程序是adb logcat.我改变了现有的功能:
(defun adb-logcat ()
(interactive)
(shell-command "adb logcat -v threadtime&" "*adb-logcat*")
(pop-to-buffer "*adb-logcat*")
(buffer-disable-undo))
Run Code Online (Sandbox Code Playgroud)
以下内容:
(defun adb-logcat ()
(interactive)
(start-process "*adb-logcat*" "*adb-logcat*" "/bin/sh" "-c" "adb logcat -v threadtime")
(pop-to-buffer "*adb-logcat*")
(buffer-disable-undo))
Run Code Online (Sandbox Code Playgroud)
它现在滚动得更快.好极了!
我编写了这个简单的脚本,它每秒生成一个输出行(generator.sh):
\nfor i in {0..5}; do echo $i; sleep 1; done\n
Run Code Online (Sandbox Code Playgroud)\nraku 程序将启动此脚本并在出现这些行时立即打印它们:
\nmy $proc = Proc::Async.new("sh", "generator.sh");\n$proc.stdout.tap({ .print });\nmy $promise = $proc.start;\nawait\xc2\xa0$promise;\n
Run Code Online (Sandbox Code Playgroud)\n一切都按预期进行:每一秒我们都会看到一条新线。但是让我们用 raku 重写生成器(generator.raku):
\nfor 0..5 { .say; sleep 1 }\n
Run Code Online (Sandbox Code Playgroud)\n并将程序的第一行更改为:
\nmy $proc = Proc::Async.new("raku", "generator.raku");\n
Run Code Online (Sandbox Code Playgroud)\n现在出了点问题:首先我们看到输出的第一行(“0”),然后长时间停顿,最后我们看到输出的所有剩余行。
\n我尝试通过命令获取生成器的输出script
:
script -c \'sh generator.sh\' script-sh\nscript -c \'raku generator.raku\' script-raku\n
Run Code Online (Sandbox Code Playgroud)\n在十六进制编辑器中分析它们,看起来它们是相同的:在每个数字之后,字节0d
和0a
后面。
为什么使用看似相同的发电机会产生如此大的差异?我需要理解这一点,因为我将启动一个外部程序并在线处理其输出。
\n我的目标是使用zenity --progress创建一个带有HandBrakeCLI输出的gtk进度条.我遇到了一些障碍,我想知道是否有人知道更好的方法,或者可以帮助我解决我目前正在做的事情.
正常输出:
HandBrakeCLI -i infile -o outfile --preset=iPad
Run Code Online (Sandbox Code Playgroud)
显示器
编码:任务1的1,1.9.97%(72.81 fps,平均86.78 fps,ETA 00h00m43s)
HandBrake用管道输入tr并削减命令,因此我只有zenity所期望的百分比.
HandBrakeCLI -i infile -o outfile --preset=iPad 2>&1 | tr -s '\r' '\n' | cut -b 24-28
Run Code Online (Sandbox Code Playgroud)
结果我期望:
1.05
1.06
1.10
1.10
Run Code Online (Sandbox Code Playgroud)
但是,输出延迟很多,有时甚至不会显示.如果我只使用我的tr表达式,我会在每一行上面得到输出,但它是整个输出,包括"编码:任务......".
这就像cut命令无法跟上Handbrake的标准.我读到了使用命名管道,创建了一个并将HandBrake的输出定向到管道,然后在另一个终端通过管道尝试了tr和cut命令,它导致相同的延迟.
使用awk的print子字符串也会导致相同的延迟.
我无法弄清楚.我正在使用zenity --progress指标,因为我的HandBrake作业被称为MythTV工作,我想要一个进度条弹出,所以我知道什么时候和编码正在进行中.
我正在运行一个使用 emscripten 编译为 wasm 的 C 工具。该工具适用于非常大的文件。在 CLI 上正常运行此工具时,通常操作会传输结果并在返回足够的数据后提前终止程序。例如你可以运行:
./tool <input-file> | head -n 100
该工具将在检测到 stdout 已被 关闭后终止head
,实际上仅读取一小部分输入。
问题是带有 emscripten 的 stdout 似乎是异步的(通过覆盖 Module.print),因此该工具每次都会运行完成。有没有办法让它在标准输出上阻塞,这样我只能读取我需要的内容,然后终止该工具?
通常,如果我想打印命令的输出,并在文件中捕获该输出,tee就是解决方案。但我正在使用一个似乎有特殊行为的实用程序制作一个脚本。它就是wps无线评估工具bully。
如果我正常运行 bully 命令(不带 tee),输出将以标准方式逐步显示。但是,如果我将管道放在末尾这样进行记录,| tee "/path/to/my/logfile"
屏幕上的输出就会冻结。在命令结束之前它什么也不显示。结束后,它一次性显示所有内容(不是一步一步),当然它也将输出放入日志 tee 文件中。
bully 命令的示例:bully wlan0mon -b 00:11:22:33:44:55 -c 8 -L -F -B -v 3 -p 12345670 | tee /root/Desktop/log.txt
为什么?不确定这是否只发生在恶霸身上,或者是否还有其他程序具有相同的行为。
是否有另一种方法可以将输出捕获到实时在屏幕上显示输出的文件中?
系统:Linux 4.13.0-43-generic #48~16.04.1-Ubuntu BASH_VERSION='4.3.48(1)-release'
命令:
while sleep 5
do
date +%T
done | awk -F: '{print $3}'
Run Code Online (Sandbox Code Playgroud)
应打印“日期”输出的第三个字段(秒),每 5 秒一行。问题:仅当管道缓冲区已满时,awk 才从管道读取数据并处理其输入。即当生成超过 4K 的输入时。
当awk被cat替换时,按预期每 5 秒打印一行。
这段代码是从一个在其他系统上运行良好的 shell 脚本简化而来的,所以这个系统中肯定有一些关于 bash、awk 及其配置的内容。
简而言之,有没有办法说服awk在从管道读取数据时表现得像cat一样?
@Ed Morton:我确实尝试在每次打印后添加fflush(),但它不起作用——这表明问题出在 awk 的输入上,而不是输出上。我还尝试添加对system("date")的调用,这表明 awk 确实一次获取所有输入行,而不是在生成它们时立即获取。
对于那些提问的人:
$ awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
compiled limits:
max NF 32767
sprintf buffer 2040
Run Code Online (Sandbox Code Playgroud) 我想要实现的目标:
echo input | my_function
echo input | my_function | my_function
结果为\t\tinput
.至于我的测试,请看以下脚本:
#!/usr/bin/env bash
main() {
echo 'first:'
echo 'once' | tab_indent_to_right
echo 'twice' | tab_indent_to_right | tab_indent_to_right
{
echo 'wait 2 sec'
sleep 2
echo 'wait 2 sec'
sleep 2
echo 'waited'
} | tab_indent_to_right
}
tab_indent_to_right() {
# while read -r line; do echo $'\t'"$line"; done # double indent not working
# awk -v prefix='\t' '{print prefix $0}' # buffer not …
Run Code Online (Sandbox Code Playgroud)