1

I've written a program in ruby called citeselect that uses curses to dynamically select a reference from a bibtex bibliogrpahy. I would like to put this program into a pipeline to cite anything easily using the output of this program. Unfortunately, as I found out from Ncurses and linux pipeline (c), Curses uses stdout for its display.

Therefore, I've routed the output citation key into file descriptor 3 when it is provided as an output. I've verified that it works:
citeselect 3>output

Is there any way to capture the output sent to fd3 in a one liner in bash? Something like
echo "The citation key is $(citeselect 3>)"

Thanks.

vividn
  • 65
  • 1
  • 5
  • 1
    You're close. `3>&1` will copy file descriptor 3 to file descriptor 1 (standard output). If curses actually writes to standard output (and not directly to the terminal), you'll also need to go through some contortions to avoid capturing it as well. – chepner Jul 01 '17 at 21:15

2 Answers2

1

Using Victory's answer as a starting point, and after experimenting around with output redirection, I realised that I had the wrong idea about what n>&m did. This guide really helped me:
http://mywiki.wooledge.org/BashFAQ/002

To do this I have to redirect stdout to stderr, and then fd3 to stdout like this:
CITATION=$(citeselect 3>&1 1>&2)

That way curses is still able to use the tty via the stderr stream, while I can still pipe the citation output. In a lot of my earlier attempts, I had the redirection arguments reversed because of a fundamental misunderstanding of what they were doing.

vividn
  • 65
  • 1
  • 5
0

Nice question, a much better way to do this is to replace the stdout file descriptor with another number using the exec command:

#!/usr/bin/env bash

exec 3>&1             # 1 is stdout, 3 is the fd to assign stdout to

exec > outputfile.txt # every command executed within this location 
                      # to where the fd was closed and replaced back 
                      # to it's formal value will be sent to outputfile.txt


citselect

exec 1>&3 3>&-        # the fd of stdout is replaced back to 1 and reset

Put this file in your ${HOME}/bin or /usr/bin/ folder and execute it instead of calling citeselect directly

For more information about this, check the Advanced Bash Guide, but in some cases you should avoid using that Guide for reference.

agc
  • 7,973
  • 2
  • 29
  • 50
0.sh
  • 2,659
  • 16
  • 37