Bash脚本将stdin重定向到程序并将其输出重定向到另一个程序 [英] Bash script redirecting stdin to program and its output to another program

查看:156
本文介绍了Bash脚本将stdin重定向到程序并将其输出重定向到另一个程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在学习bash脚本。这是我第一次将输出重定向到另一个程序,我不知道该怎么做。

I'm just learning bash scripting. It's the first time I have to redirect output to another program and I don't know how to do it.

我必须编写一个连接GUI程序的脚本,和零,一个或两个程序 - 我需要两个玩家,都可以是计算机或人类。 GUI从两个程序(或人类,我的意思是从标准输入)获得输出。

I have to write a script which connects a GUI program, and zero, one or two programs - I need two players, both can be computer or human. GUI gets output from both programs (or humans, I mean from stdin).

假设有一个人和一个comp_player。 Human使用stdin命令,必须将此命令重定向到正在运行的GUI程序并运行comp_player,两者都需要输入。然后,comp_player的输出必须重定向到GUI(如果有第二台计算机播放器,则还需要将此输出重定向到第二台计算机播放器的输入)。转弯结束。

Let's assume that there is one human and one comp_player. Human gives command using stdin, this command has to be redirected to running GUI program and running comp_player, both expecting input. Then, comp_player's output has to be redirected to GUI (if there were second computer player, it would also be necessary to redirect this output to second computer player's input). The turn ends.

我知道如何创建一个文件来读写,并重定向输入或输出。例如:

I know how to create a file to read and write and redirect input or output from it. For example:

echo "anything" >&3
exec 3<>sometextfile
read line <&3
echo $line

但我不知道是如何重定向,例如,我刚刚读到的行,正在运行的程序谁需要输入并捕获其输出,我可以重定向到GUI和另一个程序。

But what I don't know is how to redirect, for example, line I just read to running program who expects input and capture its output, which I can redirect to GUI and another program.

我知道它不像上面的代码那么简单,我必须使用一个叫做命名管道的东西,但我试着阅读一些教程,但我没有编写工作脚本。

I know it isn't as simple as code above and I that have to use something called named pipes, but I tried to read some tutorials and I failed to write working script.

你能给我一个脚本片段的例子,比如说:

Can you give me an example of fragment of a script which, say:

(gui程序和电脑播放器程序正在运行)

(gui program and computer player program are running)

-sts来自stdin的行

-reads line from stdin

- 发送行到gui程序和comp_player的输入

-"sends" the line to gui program's and comp_player's inputs

- 从comp_player读取输出并将其写入stdout并将其发送到gui输入

-"reads" output from comp_player and writes it to stdout and also "sends" it to gui input

推荐答案

命名管道是的用于连接两个完全独立程序的输入和输出的特殊文件。可以将其视为临时缓冲区,或者是两个彼此不了解的程序之间共享的数组。这使得它们成为在两个程序之间共享消息并使它们非常有效地进行通信的绝佳工具。

Named pipes are a special kind of files used to connect the input and output of two completely separate programs. Think of it as a temporary buffer, or an array that's shared between two programs that don't know about each other. This makes them an awesome tool to share messages between the two programs and get them to communicate very effectively.

作为查看命名管道如何工作的简单测试,打开两个终端在同一目录中,并在第一个中键入 mkfifo mypipe 来创建文件。现在,使用它只是写一些东西,例如:

echo一条非常重要的消息> mypipe

As a simple test to see how a named pipe works, open two terminals in the same directory, and type mkfifo mypipe in the first one to create the file. Now, to use it just write something to it, for example:

echo "A very important message" > mypipe

现在消息存储在管道文件中,您将看到终端被阻止,好像 echo 还没有完成。转到第二个终端并使用以下方法获取管道内容:

cat mypipe




您将从第一个终端打印出存储在管道中的非常重要的消息。注意管道现在是空的,你根本无法再从中获取消息。

Now the message is stored in the pipe file, you will see the terminal is blocked, as if the echo hadn't finish. Go to the second terminal and get the contents of the pipe using:

cat mypipe

You will print out the "very important message" you stored in the piped from the first terminal. Notice the pipe is empty now, and you simply can't get the message again from it.

现在你知道命名管道是如何工作的,这是三个玩家如何沟通的一个非常简单的例子。请注意,我们不能为所有这些文件使用单个文件,而是创建单独的管道来传达player1和player2,player1和gui,以及player2和gui。我猜gui程序是用另一种语言编写的,但我会把它留给你。

Now that you know how named pipes work, here's a very simple example of how three players would communicate. Notice that we can't use a single file for all of them, instead we will create separate pipes to communicate player1 and player2, player1 and gui, and player2 and gui. I'm guessing the gui program is written in another language, but I will leave that to you.

PLAYER 1(HUMAN)

player2pipe="pipe1"
guipipe="pipe2"

#First make sure we have our files
if [ ! -p $player2pipe ]; then
    mkfifo $player2pipe
fi

if [ ! -p $guipipe ]; then
    mkfifo $guipipe
fi


while true; do #Or until the game ends
    echo -n "Do something: "
    read move
    # Send our move to the other two players
    echo $move > $player2pipe
    echo $move > $guipipe

    playermove=$(cat $player2pipe) # Read other player's move from the pipe file. The execution will pause until there's something to read

    # Do something about that move here

done

PLAYER2(计算机)

player1pipe="pipe1"
guipipe="pipe3"


if [ ! -p $player1pipe ]; then
    mkfifo $player1pipe
fi

if [ ! -p $guipipe ]; then
    mkfifo $guipipe
fi


while true; do

    playermove=$(cat $player1pipe)

    # Do something about that move here

    move="A very good move made by a computer" #Obviously you will have to generate a new move
    echo $move > $player1pipe
    echo $move > $guipipe

done

GUI

player1pipe="pipe2"
player2pipe="pipe3"

if [ ! -p $player1pipe ]; then
    mkfifo $player1pipe
fi

if [ ! -p $player1pipe ]; then
    mkfifo $player1pipe
fi


while true; do #Or until the game ends

    # Read other players' move from the pipe files. Notice the order here, if player2 moved before player1 the execution would be locked until the pipe is emptied
    player1move=$(cat $player1pipe)
    player2move=$(cat $player2pipe)

    #Print out their move or whatever you need to do with it.
    echo $player1move
    echo $player2move

    # Do whatever else you need to do about those moves
done



将三个文件保存在同一目录中,并从三个不同的终端执行它们以查看它们的工作原理。
希望我帮忙。


Save the three files in the same directory and execute them from three different terminals to see how they work. Hope I helped.

这篇关于Bash脚本将stdin重定向到程序并将其输出重定向到另一个程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆