4

How to write the analogue of a bash-command like:

(cd ../repo && git fast-export master) | darcs convert import repo_master

in eshell?

Here a subshell is employed to restrict the effect of cd.

2 Answers2

3

In eshell, process subshells are generally done with ${...} syntax. However, the output is produced in the form of an intermediate Emacs Lisp expression.

~ $ echo ${cd ~/.emacs.d; ls} | cat
("README.md" "ac-comphist.dat"
  #("auto-save-list" 0 14
     (font-lock-face eshell-ls-directory))
  #("bin" 0 3
     (font-lock-face eshell-ls-directory))
  "custom.el"
[more text omitted]

While this is useful if you want to chain Elisp expression, it is not if you want to pass a raw string. Instead, you might want to use the command eshell-command-result.

~ $ echo (substring-no-properties (eshell-command-result "cd ~/.emacs.d; ls")) | cat
README.md
ac-comphist.dat
auto-save-list
bin
custom.el
[more text omitted]

Various modifications may help you get what you want. Just play with it and see how it goes.

PythonNut
  • 10,243
  • 2
  • 29
  • 75
  • Thanks, that's interesting! I have a question about `${}`. How is it supposed to be used? Normally, elisp expressions dont't read stdin, so one must invent something complex after a `${...} |`, true? – imz -- Ivan Zakharyaschev Jan 24 '15 at 09:05
  • 1
    By experimenting, I found out more about `{ }` (behaves similarly to `${ }`) -- http://emacs.stackexchange.com/a/7688/5165 . Among other things, if the thing inside `{ }` is not a builtin, then the output is never an elisp expression. So can use it for example safely. I don't know how `{ }` and `${ }` differ. – imz -- Ivan Zakharyaschev Jan 24 '15 at 10:21
2

{ ... } has very varying behavior (at least, from the point of view of bash):

~ $ {echo a b c} | tr [[:lower:]] [[:upper:]]
("A" "B" "C")~ $ 
~ $ {echo hi} | tr [[:lower:]] [[:upper:]]
HI~ $ {/bin/echo a b c} | tr [[:lower:]] [[:upper:]]
~ $ A B C

~ $ echo {echo a b c}
("a" "b" "c")
~ $ echo {/bin/echo a b c}
~ $ echo {/bin/echo hi}
~ $ echo {echo hi}
hi
~ $ echo ${/bin/echo hi}
~ $ 

As you can see:

  • a builtin inside { } feeds its output to a pipe AND provides it as the substitution when used as an argument of a command. Another peculiarity is that:

    • if the output consists of one "element", it is output in its bare form,
    • but a list is output as an elsip list.
  • A Unix program inside { } feeds its output to a pipe AND NEVER makes it a substitution in an argument position. There is also no special treatment of lists, no elisp expressions appear as the output.

I'm not sure whether ${ } does exactly the same as { } or there are some differences...

  • It looks like the dollar sign is there so you can use it in a string. Namely, you can do `cd /a/${echo b}/c`. If you're using it as its own word, the dollar sign is not needed. – PythonNut Jan 24 '15 at 17:18