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.

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.

  • 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 9:05
  • 1
    By experimenting, I found out more about { } (behaves similarly to ${ }) -- 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.