在bash中打开命名管道,无需读取或写入

时间:2014-07-14 06:21:49

标签: ruby linux bash shell named-pipes

我想在bash中使用命名管道而不读取或写入它,直到发生事件。我需要在shell脚本运行的整个过程中保持此管道打开。每当我需要时,我都会从中读取。意思是,可以这样做:

open(<$NAMED_PIPE>, "r+")
--do something--
--call child ruby script, which will write to named pipe--
--do something more---
read line < $NAMED_PIPE

在bash中这可能吗?

我使用以下代码: ../红宝石 | - try1.rb ` - try2.sh

try1.rb如下:

#!/usr/bin/ruby

require 'optparse'

puts 'Hello World!, This is my first ruby program'

options = {}

optparse = OptionParser.new do|opts|

  opts.banner = "Featbuild minimal trial script for command line parsing"

  options[:cpl] = nil
  opts.on('--cpl SWITCH_STATE', 'compile on or off') do|cplopt|
      options[:cpl] = cplopt
      OPT_CPL=cplopt
      puts cplopt
  end

  opts.on('-h', '--help', 'Display this screen') do
    puts opts
    exit
  end
end

optparse.parse!

output = open("mypipe", "w+")

output.puts OPT_CPL
output.flush

try2.sh脚本(调用ruby脚本):

#!/bin/sh



mkfifo mypipe
exec 4< /home/yusufh/Ruby/mypipe

OPT=$*
./try1.rb ${OPT}


#read -ru 4 line
read line <&4

echo $line


exec 4<&- #close FIFO my_pipe

rm mypipe

@konsolebox,当我使用普通文本文件从ruby脚本中复制数据时,您的解决方案正常工作,并且bash脚本从那里获取它。 但是,在尝试使用命名管道时,bash脚本在执行以下语句后阻塞:exec 4< /home/yusufh/Ruby/mypipe。控件无法生成ruby脚本进程,其中数据将被生成,之后bash脚本的实际等待/阻塞必须在此行完成:read line <&4。 因此,我想要实现的目标不会发生。另外,当bash在获取FIFO的fd时等待,如果我在重复终端上的某个命名管道中回显某些内容,那么它就会等待并继续进行。但是在这种情况下,正如我所观察到的那样,从Ruby脚本返回的数据也没有写入FIFO。这是调试模式中scritps的输出:

[yusufh@verigybuild6 Ruby]$ bash -xv try2.sh --cpl on &
[1] 2777
[yusufh@verigybuild6 Ruby]$ #!/bin/sh



mkfifo mypipe
+ mkfifo mypipe
exec 4< /home/yusufh/Ruby/mypipe
+ exec

[yusufh@verigybuild6 Ruby]$ echo "Hello World" > mypipe
[yusufh@verigybuild6 Ruby]$
OPT=$*
+ OPT='--cpl on'
./try1.rb ${OPT}
+ ./try1.rb --cpl on
Hello World!, This is my first ruby program
on


#read -ru 4 line
read line <&4
+ read line

echo $line
+ echo Hello World
Hello World


exec 4<&- #close FIFO my_pipe
+ exec

rm mypipe
+ rm mypipe



[1]+  Done                    bash -xv try2.sh --cpl on
[yusufh@verigybuild6 Ruby]$

为什么会失败的任何想法?我很感激努力! : - )

2 个答案:

答案 0 :(得分:4)

Bash非常简单:

# Open the named pipe with a custom fd for input
exec 4< /path/to/named_pipe

# Do other things
:

# Read a line from pipe
read -ru 4 line

# Or
read -r line <&4

# Just make this consistent and close it when you're done. May not be necessary at exit but still a good practice.
exec 4<&-
  • 使用read阅读输入时,最好使用-r来防止反斜杠转义任何字符
  • 使用read未设置(IFS)运行IFS= read ...也可能有助于防止修剪前导和尾随空格。

类似的概念适用于写作:

exec 4> /path/to/named_pipe
echo something >&4
exec 4>&-

奖励:您还可以在{}whileforifuntil等块的范围内打开命名管道..没有必要关闭文件描述符:

{
    # Do reads and other things
    ...
} 4< /path/to/named_pipe

答案 1 :(得分:0)

如果没有关于你的脚本管道权限的信息,这里有一个我能想到的可能选项。

1)打开管道mkfifo /path/to/pipe

2)做一些事情echo test1

3)调用子ruby脚本,它将写入命名管道(假设脚本可执行)/path/to/script >> /path/to/pipe &

4)做更多事情echo test2

5)从管道read pipeddata < /path/to/pipe

读取行