Capturing file descriptor 3, or alternatives.

Ben Scott dragonhawk at gmail.com
Tue Jun 26 13:52:50 EDT 2012


On Tue, Jun 26, 2012 at 11:51 AM, Bill Freeman <ke1g.nh at gmail.com> wrote:
> But I have to provide two different values, for four different
> environment variables to get the job done.  I was thinking about how
> to pack two values into one table (displayed in the menu), and doing
> the splitting of stuff in bash ...

  bash provides shell variables arrays, which might be yet another way.

  I don't know what the two values you have to give to git are.  For
the sake of example, I'll suppose they are the user ID and the project
directory (I have no idea if these concepts even apply; it's an
example).  Your table could then be:

	name[1]="Alice     WOMBAT "   ; user[1]=alice     ; pdir=/proj/wombat
	name[2]="Alice     PEBKAC "   ; user[2]=alice     ; pdir=/proj/pebkac
	name[3]="Bob       WOMBAT "   ; user[3]=bob       ; pdir=/proj/wombat
	name[4]="Charlie   WOMBAT "   ; user[4]=charles   ; pdir=/proj/wombat
	name[5]="Charlie   PICNIC "   ; user[5]=charles   ; pdir=/proj/picnic

> ... when I said to myself "why should I
> struggle with this in bash when python is there?".

  Yet another thing you could do would be to have the shell exec your
Python script (replacing itself with Python), have Python do whatever
you need to do (set environment, etc.), and then have Python exec
itself back to a shell.   It's a bit kludgy and loses unexported shell
state, though.

> 4. Therefore, if my python script gets invoked in back ticks or $(), I
> should be able to count on:
> 4a. stdin (fd 0) and stderr (fd 2) have the tty open for reading and
> writing respectively.
> 4b. stdout (fd 1) will be the input end of a pipe back to the parent shell.

  stderr is conventionally reserved for error messages (obviously),
and additionally, it is conventionally opened unbuffered.  I'd suggest
thus instead using stderr as your out-of-band channel, and have your
script to user interaction using stdin.  You can capture the output of
stderr in a command substitution using that method I found of swapping
file descriptors:

	eval $( your_script.py 3>&1 1>&2 2>&3 3>&- )

  I believe the above should be fairly portable, even if your shell isn't Bash.

  The more sophisticated technique which I posted later lets you use a
entirely separate file descriptor, leaving both stdout and stderr as
normal, but I don't think it will work in anything other than Bash.

-- Ben



More information about the gnhlug-discuss mailing list