如何在 shell 之间传递数据而不读取/写入中间文件

如何在 shell 之间传递数据而不读取/写入中间文件

假设我有一个在 shell 中运行的进程正在回显用户输入。那么如何从另一个终端将数据传递到该 shell 或从该 shell 传递数据呢?是否可以不使用中间文件?

例如,如果我有代码

fgets(string, LEN, stdin);
printf("%s", string);

那么,是否可以通过不同的 shell将数据传递给stdin并从中获取数据?stdout

答案1

我不太确定我是否明白你的意思,但是。

在单个 shell 会话(终端)中,您可以使用管道将数据从一个命令传递到另一个命令,如下所示:

$ ls -l | grep something

如果需要在两个不同的 shell 之间执行此操作,可以使用命名管道:

tty1$ mkfifo /tmp/mypipe
tty1$ ls -l > /tmp/mypipe
tty2$ grep something < /tmp/mypipe

mktemp使用创建一个目录来放置命名管道会更安全:

tty1$ dir=$(mktemp -d)
tty1$ mkfifo "$dir/mypipe"
tty1$ ls -l > "$dir/mypipe"
tty1$ rm -r "$dir"

尽管这需要将路径复制到另一个窗口,可能是手动的。

当然,命名管道的作用有点像中间文件,因为它需要路径名。但它的行为更像是一个管道,因为数据不会写入永久存储,如果写入器速度较慢,则读取器会等待写入器,而不是可能遇到过早的文件结束。

(您通常会使用ls -l *something*代替ls | grep,但它可以作为示例。)

答案2

我认为@ilkkachu 的回答很有帮助,并且提供了您所需要的。我会尝试用一些细节来解释,同时我会学习如何使用fifo。

  • 在同一台电脑上准备两个命令行窗口w1和w2

  • 创建监听program,我在w1中做了一个shellscript

    #!/bin/bash
    
    while true
    do
     read string
     if [ "${string:0:4}" == "Stop" ]
     then
      printf "Gotcha\n"
      break
     elif [ "$string" != "" ]
     then
      printf "$string "
     else
      sleep 3
     fi
    done
    
  • 在w1中准备fifo

    dir=$(mktemp -d)
    mkfifo "$dir/mypipe"
    
  • 启动程序并让它等待w1中fifo的输入

    < "$dir/mypipe" ./program
    
  • 查找 fifo 并在 w2 中回显一些字符串

    $ find /tmp -name mypipe 2>/dev/null
    /tmp/tmp.dRhpqajJqz/mypipe
    
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo qwerty
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo asdf
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo Stopp
    
  • 查看w1中的输出

    qwerty asdf Gotcha
    $ 
    

您还可以使其更加自动化,例如如下所示,它假设只有一个名为 的临时文件mypipe

  • 在w1中再次启动程序

    < "$dir/mypipe" ./program
    
  • 在w2中

    > $(find /tmp -name mypipe 2>/dev/null) echo 'Hello World'
    > $(find /tmp -name mypipe 2>/dev/null) echo 'Stop the World'
    
  • 查看w1中的输出

    Hello World Gotcha
    $
    

演示 C 程序,

#include <stdio.h>
#include <string.h>

int main () {

 char string[21];
 while(1){
    fgets(string, 20, stdin);
    string[strlen(string)-1] = 0;
    if(strcmp("Stop", string) == 0){
        printf("Gotcha");
        return 1;
    }
 }
}

该 C 程序仅在读取“停止”时才进行写入。

相关内容