5

I was just curious if there's a way to get input not from StdIn but from $EDITOR - be it vim, nano, emacs or even a non-command-line-editor (MacVim/TextMate). What are the options/workarounds/bestpractices?

Basically I'd wish for a workflow as with heredoc - but from the $editor instead.

$ sort -nr << FOO | uniq -c 
pipe heredoc> foo 
pipe heredoc> bar
pipe heredoc> baz
pipe heredoc> foo
pipe heredoc> FOO
   2 foo
   1 baz
   1 bar
nocksock
  • 305
  • 1
  • 2
  • 8
  • 2
    I'm not sure what you mean by "get input from an editor," could you clarify just how you think the process should go? – Kevin Mar 22 '12 at 14:07
  • @Kevin I hope the heredoc example makes it clearer. – nocksock Mar 22 '12 at 16:27
  • @NilsRiedemann: So in this example in place of `heredoc` there should be opened text editor that allows you to input text, and after you quit editor all that you write in it is treated as input to sort and uniq? – pbm Mar 22 '12 at 16:32
  • How about just using a temporary file? – Kevin Mar 22 '12 at 16:43
  • @pbm yup, exactly. – nocksock Mar 22 '12 at 18:22
  • possible duplicate of [Piping commands, modify stdin write to stdout](http://unix.stackexchange.com/questions/125580/piping-commands-modify-stdin-write-to-stdout) – Graeme Apr 19 '14 at 20:16
  • @Graeme No, not a duplicate. This is the original... – Bernhard May 02 '14 at 08:47
  • @Bernhard, if you look at the conversation on the other question you will see why I suggested marking this one as the dupe. It is not necessarily the one that was chronologically first that is best to keep open. – Graeme May 02 '14 at 12:02
  • @Graeme It doesn't make sense to have them both closed at the same time pointing to eachother. This confuses reviewers. – Bernhard May 02 '14 at 12:54
  • @Bernhard, at the time I made the comments, both questions were open and the idea was that only this one should be closed. – Graeme May 02 '14 at 13:21
  • @Graeme Ok, now it is clear to me. – Bernhard May 02 '14 at 13:24

4 Answers4

7

The command vipe in the package moreutils allows you to launch $EDITOR in the middle of a pipeline.
You can get the desired behaviour like so:

$ </dev/null vipe |sort -nr | uniq -c 
3

I guess your only chance to make it work with any kind of editor is to use temporary files:

FILE=$(mktemp); $EDITOR "$FILE"; <"$FILE" …command… ; rm "$FILE"

(However this does not allow to start the command before a complete input is provided.)

Also you can use echo "# please insert your input bellow" >"$FILE" before the call to $EDITOR to insert a comment that will show up inside the editor. Be sure that it won't affect the behavior of the command (or ask the user to explicitly remove it).

Stéphane Gimenez
  • 28,527
  • 3
  • 76
  • 87
  • 2
    Also, notice that `rlwrap command` allows line editing (with history) from the terminal and might be enough for your needs. – Stéphane Gimenez Mar 22 '12 at 15:11
  • 1
    It is also common to pre populate the file with some comment lines giving instructions. – psusi Mar 22 '12 at 15:22
  • Can you expand the example to have a prefilled tempfile like psusi describes? Besides your example does not work - it lacks an argument. Seems like this answer is the way to go. Also: why is it `<"$FILE" command;` not `command <"$FILE";`? – nocksock Mar 22 '12 at 18:20
  • @Nils: See the edit. `command` was meant to be replaced by the actual command :-) And for the last question: it's the same. – Stéphane Gimenez Mar 22 '12 at 18:31
  • When I use `FILE=$(mktemp); $EDITOR "$FILE"; <"$FILE" sort -c; rm "$FILE"` I get `usage: mktemp [-d] [-q] […shortened]` and `zsh: no such file or directory:\n rm: : No such file or directory` :/ Vim also opens, but i can't save the file (no filename) – nocksock Mar 22 '12 at 18:37
  • Then, we don't have the same `mktemp`, refer to your man page. – Stéphane Gimenez Mar 22 '12 at 18:39
0

Emacs has the possibility to run the shell in one of its buffer (use M-X shell). But the launched processes would still get their input from stdin, their stdin would simply be a pseudo-terminal whose other end would be emacs.

AProgrammer
  • 2,278
  • 18
  • 15
0

In Emacs you can run any command and provide content of one of Emacs buffers (selected region to be exact) as stdin to application.

For example if content of your Emacs buffer will be ls and you mark it as region (using C-SPC), then run shell-command-on-region (M-|) and type as command bash (full combination: M-| command RET) there will be ls executed in bash and output will be opened as new buffer.

If you use C-u M-| command RET on region, output will replace marked command in your current buffer.

pbm
  • 24,747
  • 6
  • 36
  • 51