假设我有一个在 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 程序仅在读取“停止”时才进行写入。