2011-09-01 56 views
8

时停止有没有办法告诉cat命令停止未接收到任何数据时读?也许用一些“超时”来指定没有数据传入的时间。猫阅读:不接收数据

任何想法?

+0

你不只是在寻找'read'吗? – Wrikken

+0

我可以读取管道吗? – Kai

+0

cat $ fifo |而nc ... – Kai

回答

5

cat本身,没有。它读取输入流,直到告诉它是文件的结尾,如果需要的话阻塞输入。

没有什么可以阻止你写你自己的cat相当于将使用select标准输入超时,如果没有足够快即将到来,并退出在这些条件下。

事实上,我曾经写过一个snail程序(因为蜗牛比猫慢),它每秒钟额外增加一个字符参数来缓慢输出文件(a)

所以snail 10 myprog.c将以每秒10个字符输出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 

(一)事实上,它被称为slowcatsnail是好得多,我不是有点轻微修正主义的上面,如果它使故事听起来更好:-)

+0

你会怎么做? – Kai

+0

@凯,我已经将代码发布到'snail'程序。 – paxdiablo

+0

puuuh我想我不明白。我对c不是那么普遍。 – Kai

5

有是一个timeout(1)命令。例如:

timeout 5s cat /dev/random 
+0

并且如果没有来自/ dev/random的输入超过5s,这会取消cat? – Kai

+0

不,这只会阻止猫。然后,您可以分析输出以查看是否存在某些内容。 –

+0

但我想阻止猫只是如果没有更多的数据来自/ dev /随机超过x秒 – Kai

1

这里是超时猫代码:

#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没有参数 - catting标准输入。作为第一个参数提供超时秒数。

一个限制(适用于狗也一样) - 行是行缓冲,让你有正秒提供线(未任何字符)复位超时报警。这是因为readline。

使用

,而不是潜在不已:

cat <some_input> some_output 

你可以做编译上面timeout_cat代码:

./timeout_cat 5 <some_input> some_output 
+0

抱歉,但我没有得到它的工作。我试过“./timeout-cat/dev/input/event4 5”(event4是我的键盘) – Kai

+0

不,它的行为像'cat'命令没有任何参数。唯一的参数是超时。 –

+0

paxdiablo的解决方案有什么不同?这只是一个设计问题吗? – Kai

0

尽量考虑尾-f --pid 我假设你正在读一些文件,当制片人完成(走了?)你停止。

将处理/ var/log/messages直到watcher.sh完成的示例。

./watcher.sh& 
tail -f /var/log/messages --pid $! | ... do something with the output 
+0

尼斯。不幸的是它不在我的尾巴上。我希望它只是Gnu。 – dubiousjim

-1

只需猫,然后在5秒后杀死猫。

cat xyz & sleep 5; kill $! 

获取猫输出作为回复5秒

reply="`cat xyz & sleep 5; kill $!`" 
echo "reply=$reply" 
+0

如果一段不确定的时间数据产生过程输出(可能是一分钟,可能是天),然后停止?即使源代码仍然在输出数据,您只能获得前五秒钟。 – Piskvor

+0

是的,这是事实。所以你必须使用这个逻辑的最大可能超时。即当答复对你无用时。 – Oguz

+0

问题是,最大可能的超时是未知的;并得到一个通知“该过程可能在上周有时候完成了输出数据(或者可能不是,也许我们只是杀死它)”比无用的更糟糕。 – Piskvor

0

mbuffer后,以其-W的选择,为我工作。

我需要沉stdin到一个文件,但有一个空闲超时:

  • 我并不需要真正连接多个源
  • (但也许有办法使用mbuffer这一点。)我不需要任何cat可能的输出格式选项。
  • 我不介意mbuffer带来的进度条。

根据链接手册页中的建议,我确实需要添加-A /bin/false来抑制警告。我的复制stdin到10秒的空闲超时文件的调用最终看起来像

mbuffer -A /bin/false -W 10 -o ./the-output-file