有没有办法告诉cat
命令在没有收到任何数据时停止读取?可能有一些“超时”,指定没有数据传入的时间。
有任何想法吗?
有一个timeout(1)
命令。例子:
timeout 5s cat /dev/random
视你的情况而定。例如,您使用 -e 运行 bash 并通常关心退出代码。
timeout 5s cat /dev/random || true
cat
本身,没有。它读取输入流,直到被告知文件结束,必要时阻塞输入。
没有什么可以阻止您编写自己的 等效项,如果没有任何事情足够快地出现cat
,它将在标准输入上使用超时,并在这些条件下退出。select
事实上,我曾经写过一个snail
程序(因为蜗牛比猫慢),它每秒需要一个额外的字符参数来缓慢输出一个文件(a)。
所以snail 10 myprog.c
将以myprog.c
每秒十个字符的速度输出。对于我的一生,我不记得我为什么这样做——我怀疑我只是在胡闹,等待一些真正的工作出现。
既然你遇到了麻烦,这里有一个版本dog.c
(基于我前面提到的snail
程序),它可以满足你的需求:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/select.h>
static int dofile (FILE *fin) {
int ch = ~EOF, rc;
fd_set fds;
struct timeval tv;
while (ch != EOF) {
// Set up for fin file, 5 second timeout.
FD_ZERO (&fds); FD_SET (fileno (fin), &fds);
tv.tv_sec = 5; tv.tv_usec = 0;
rc = select (fileno(fin)+1, &fds, NULL, NULL, &tv);
if (rc < 0) {
fprintf (stderr, "*** Error on select (%d)\n", errno);
return 1;
}
if (rc == 0) {
fprintf (stderr, "*** Timeout on select\n");
break;
}
// Data available, so it will not block.
if ((ch = fgetc (fin)) != EOF) putchar (ch);
}
return 0;
}
int main (int argc, char *argv[]) {
int argp, rc;
FILE *fin;
if (argc == 1)
rc = dofile (stdin);
else {
argp = 1;
while (argp < argc) {
if ((fin = fopen (argv[argp], "rb")) == NULL) {
fprintf (stderr, "*** Cannot open input file [%s] (%d)\n",
argv[argp], errno);
return 1;
}
rc = dofile (fin);
fclose (fin);
if (rc != 0)
break;
argp++;
}
}
return rc;
}
然后,您可以简单地dog
不带参数运行(因此它将使用标准输入),并且在没有活动的五秒钟后,它将输出:
*** Timeout on select
(a)实际上,它被称为slowcat
但snail
更好,如果它使故事听起来更好,我并没有超过一点小修正主义:-)
mbuffer
,有它的-W
选项,对我有用。
我需要沉入stdin
一个文件,但有一个空闲超时:
mbuffer
它。)cat
可能的输出格式选项。mbuffer
带来桌面的进度条。-A /bin/false
根据链接手册页中的建议,我确实需要添加以抑制警告。我对复制stdin
到具有 10 秒空闲超时的文件的调用最终看起来像
mbuffer -A /bin/false -W 10 -o ./the-output-file
这是超时猫的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void timeout(int sig) {
exit(EXIT_FAILURE);
}
int main(int argc, char* argv[]) {
int sec = 0; /* seconds to timeout (0 = no timeout) */
int c;
if (argc > 1) {
sec = atoi(argv[1]);
signal(SIGALRM, timeout);
alarm(sec);
}
while((c = getchar()) != EOF) {
alarm(0);
putchar(c);
alarm(sec);
}
return EXIT_SUCCESS;
}
它与 paxdiablo 的狗基本相同。它作为一个cat
没有参数的工作 - 捕获标准输入。作为第一个参数,提供超时秒数。
一个限制(也适用于 dog) - 行是行缓冲的,因此您有 n 秒的时间提供一行(不是任何字符)来重置超时警报。这是因为readline。
用法:
而不是可能无穷无尽:
cat < some_input > some_output
您可以将上面的代码编译为 timeout_cat 并且:
./timeout_cat 5 < some_input > some_output
尝试考虑 tail -f --pid 我假设您正在阅读一些文件,并且当生产者完成(消失?)时,您会停止。
将处理 /var/log/messages 直到 watcher.sh 完成的示例。
./watcher.sh&
tail -f /var/log/messages --pid $! | ... do something with the output
我在通过 adb shell 读取 tty 端口时遇到了同样的 cat 命令阻塞问题,但没有找到任何解决方案(超时命令也不起作用)。下面是我在我的 python 脚本(在 ubuntu 上运行)中使用的最后一个命令,以使其成为非阻塞的。希望这会对某人有所帮助。
bash_command = "adb shell \"echo -en 'ATI0\\r\\n' > /dev/ttyUSB0 && cat /dev/ttyUSB0\" & sleep 1; kill $!"
response = subprocess.check_output(['bash', '-c', bash_command])
只需 cat 然后在 5 秒后杀死猫。
cat xyz & sleep 5; kill $!
5秒后获取猫输出作为回复
reply="`cat xyz & sleep 5; kill $!`"
echo "reply=$reply"