Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File descriptor permission denied with bash process substitution?

I have a bash-script in which I want to communicate to the user on standard out, but also send commands to a sub-process via a file descriptor -- like this:

# ...
# ...

echo "Hello user, behold a cleared gnuplot window"

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

So I thought I could "set this up" by first starting the subprocess like this:

#!/bin/bash

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

But that yields an error:

/dev/fd/63: Permission denied

Is this to be expected?

I don't understand what's going on. (Am I doing something wrong? Can it be that my system has some special security settings, disallowing what I'm trying to do? (Running Ubuntu Linux 12.10.))

"Workaround" -- the following seems to be equivalent with what I am trying to do, and works without errors:

#!/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

Or, as one-liner:

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

Why is this working, but the initial version isn't?

Any help much appreciated.

$ bash --version
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
[...]
like image 717
Hugo Heden Avatar asked Nov 04 '22 07:11

Hugo Heden


2 Answers

You have a typo; use exec 3> >( gnuplot ) instead of exec >3 >( gnuplot ).

BTW, yes it's expected. exec >3 >( gnuplot ) redirects stdout to a file named 3, then tries to execute >( gnuplot ) (which translates to /dev/fd/63) as a program.

like image 84
Gordon Davisson Avatar answered Nov 15 '22 05:11

Gordon Davisson


I was getting:

/dev/fd/63: Permission denied

with process substitution due to use of sudo as noted here.

So don't do that:

$ sudo ruby <(echo "puts 'foo'")
ruby: Bad file descriptor -- /dev/fd/63 (LoadError)
like image 36
AXE Labs Avatar answered Nov 15 '22 06:11

AXE Labs