使用bash进程替换拒绝文件描述符权限?

时间:2013-01-07 23:25:33

标签: bash file-descriptor permission-denied process-substitution

我有一个bash脚本,我希望在标准输出中与用户通信,但也可以通过文件描述符将命令发送到子进程 - 如下所示:

# ...
# ...

echo "Hello user, behold a cleared gnuplot window"

# pass the string "clear" to gnuplot via file descriptor 3
echo "clear" >&3  

所以我想我可以通过首先启动子进程来“设置它”:

#!/bin/bash

# Initiate(?) file descriptor 3, and let it direct to a newly 
# started gnuplot process:
exec >3 >( gnuplot )

但这会产生错误:

/dev/fd/63: Permission denied

这是预期的吗?

我不明白发生了什么。 (我做错了什么?是不是我的系统有一些特殊的安全设置,不允许我正在尝试做什么?(运行Ubuntu Linux 12.10。)

“解决方法” - 以下内容似乎与我正在尝试的内容相同,并且无误地运行:

#!/bin/bash

# open fd 3 and direct to where fd 1 directs to, i.e. std-out 
exec 3>&1 

# let fd 1 direct to a newly opened gnuplot process
exec 1> >( gnuplot ) 

# fd 1 now directs to the gnuplot process, and fd 3 directs to std-out.
# I would like it the other way around. So we'll just swap fd 1 and 3 
# (using an extra file descriptor, fd 4, as an intermediary)

exec 4>&1 # let fd 4 direct to wherever fd 1 directs to (the gnuplot process)
exec 1>&3 # let fd 1 direct to std-out 
exec 3>&4 # let fd 3 direct to the gnuplot process
exec 4>&- # close fd 4

或者,作为一线:

#!/bin/bash
exec 3>&1 1> >( gnuplot ) 4>&1 1>&3 3>&4 4>&- 

为什么这样可行,但初始版本不是?

任何帮助都非常感激。

$ bash --version
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
[...]

2 个答案:

答案 0 :(得分:1)

你有一个错字;使用exec 3> >( gnuplot )代替exec >3 >( gnuplot )

顺便说一句,是的,这是预期的。 exec >3 >( gnuplot )将stdout重定向到名为3的文件,然后尝试将>( gnuplot )(转换为/ dev / fd / 63)作为程序执行。

答案 1 :(得分:1)

我得到了:

  

/ dev / fd / 63:权限被拒绝

由于使用sudo而导致进程替换here

所以那样做:

$ sudo ruby <(echo "puts 'foo'")
ruby: Bad file descriptor -- /dev/fd/63 (LoadError)