From "emacs -Q --eval '(eshell)': ~ $ (eq 'foo nil) Expecting completion of delimiter ' ... M-: (unload-feature 'em-extpipe) ~ $ (eq 'foo nil) ;; No output, since it returns nil. This is correct. (As an ironic twist, you'd normally be able to run "(unload-feature 'em-extpipe)" as a command in Eshell, but this bug prevents that from working.) I don't fully understand all the details of the code in lisp/eshell/em-extpipe.el yet, but I think this is the culprit: (while (or (eshell-parse-lisp-argument) (eshell-parse-backslash) (eshell-parse-double-quote) (eshell-parse-literal-quote))) In particular, since there are 3 single-quotes, `eshell-parse-literal-quote' throws an `eshell-incomplete' error, which gums up the works. The attached patch resolves the issue for me, but I'm not sure if it's the best strategy. If possible, I think it would be better for `eshell-parse-external-pipeline' to solely focus on finding the external pipe operators ("*|", "*<", and "*>")[1] and then for `eshell-rewrite-external-pipeline' to prepare the command string to pass to sh. This would also have the advantage[2] of making it possible to support a richer set of Eshell features with external pipes, such as the following: ~ $ echo $(message "[%s]" "hi") *| cat zsh:1: command not found: message (If you remove the "*", this outputs "[hi]", and it should be technically possible to make this work with external pipes too, provided it executes the Lisp code before generating the command string for sh.) [1] See `eshell-parse-delimiter' for an example of how that might be implemented. [2] Well, maybe there's room for debate on what the right behavior here is.