Search code examples
shellshpipeline

Launching an editor from a pipelined command


I have a script myscript that collects some information, put them in a temporary file, launches $EDITOR on that file and waits for the user to be done. Something similar to what happens with git commit when it opens $EDITOR to let you enter a commit message.

Basically myscript is

salt=$(collect_salt_from_various_sources)
password=$(openssl passwd -salt $salt $$)

tempfile=$(mktemp)
printf "username=CHOOSE A NAME\npassword=$password\n" > $tempfile

$EDITOR $tempfile
# read data from $tempfile

I would like to use my script in a pipeline, so to receive information from stdin:

# "aabbcc" will be used as part of the salt
echo "aabbcc" | myscript

The problem here is that command-line editors (e.g., Vim, Nano) cannot access the terminal any longer and the user is not able to type (almost) anything.

Is there a way to launch $EDITOR from a pipelined script so that command line editors still work?


Solution

  • The vipe command from moreutils needs to solve a similar problem and uses this technique:

    1. It writes everything from STDIN to a temporary file

      my ($fh, $tmp)=tempfile();
      print ($fh <STDIN>) || die "write temp: $!";
      close STDIN;
      
    2. It redirects STDIN and STDOUT to /dev/tty

      open(STDIN, "</dev/tty") || die "reopen stdin: $!";
      open(OUT, ">&STDOUT") || die "save stdout: $!";
      close STDOUT;
      open(STDOUT, ">/dev/tty") || die "reopen stdout: $!";
      
    3. Launches $EDITOR