1

In Bash, I have an alias of ls -Ap | grep --color=always /$ that grabs the directories of the current directory, more or less.

That said, using the same as an alias in Emacs's eShell seems to not work, at all.

It keeps grabbing files, as well, that (as far as I can tell) don't even have forward slashes anywhere in their names.

Does the forward slash mean something to eShell that it doesn't for Bash?

0

The problem seems to be something peculiar about how eshell interacts with ls, not grep.

I can confirm your example, which works fine in shell-mode or a terminal, produces long output in eshell, and includes files, not just directories. This is the same using the built-in versions of ls and grep, and also using the 'normal' versions from the operating system. That is, eshell provides its own versions of ls and grep, and if you want to use the regular versions you have to specify *ls and *grep.

For me, the output of your code, with the eshell or standard versions of the commands, produces output in columns. In normal use, ls outputs filenames in columns for interactive use, but one per line when used in a pipe. This convention isn't followed in eshell apparently. You can force the output to be one file per line with the -1 flag, :

ls -Ap1 | grep --color=always /$

I find these little edge cases pop up regularly with eshell. shell-mode doesn't include the elisp tools that eshell does, but I find it less surprising, and so easier to use.

  • Ahhh; I knew the commands were different but, from what I could see from the output, it didn't look like eShell's ls was providing anything Bash's ls wasn't. I'm so used to Bash showing the results in columns, every so often, that it didn't even occur to me that grep would read it that way, as well. Thanks for the explanation! It was really good at teasing out the points of misunderstanding. – Jaft Jan 17 at 20:05
0

eshell is not "bash in Emacs", it is its own shell. If you want to use "bash in Emacs" use shell-mode (M-x shell) instead and Emacs will run 'bash' (really, your default shell) as a sub-process. If you want to use eshell, you'll need to change your thinking a bit. Arguments that are expandable wildcards are passed to their command as an elisp list (a la ("a" "b" "c")) not a flat list (a b c). The easiest way to see this is to compare the results of echo * in bash and eshell.

bash$ mkdir foo; cd foo
bash$ touch a c; mkdir b d
bash$ echo *
a b c d
bash$

eshell$ mkdir bar; cd bar
eshell$ touch a c; mkdir b d
eshell$ echo *
("a" "b/" "c" "d/")
eshell$

Since eshell is lisp we can use a predicate to change the meaning of the wild card. (In this case only directories)

eshell$ echo *(/)
("b/ "d/")
eshell$ 

Now, about your alias in general. To "grab the directories of the current directory" I would instead use ls -d */.

bash$ ls -d */
b/ d/

eshell$ ls -d */
a b/ c d/
eshell$ ls -d *(/)
b/ d/
eshell$ ls -d *(^/)
a c

I highly recommend reading Mastering Eshell, Eshell Functions / Dealing With Wildcards and Multiple Files, and EshellAlias as they explain these aspects of eshell much more clearly than I can.

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.