2.3 Built-in commands

Eshell provides a number of built-in commands, many of them implementing common command-line utilities, but enhanced for Eshell. (These built-in commands are just ordinary Lisp functions whose names begin with eshell/.) In order to call the external variant of a built-in command foo, you could call *foo. Usually, this should not be necessary. You can check what will be applied by the which command:

~ $ which ls
eshell/ls is a compiled Lisp function in `em-ls.el'
~ $ which *ls

If you want to discard a given built-in command, you could declare an alias (see Aliases). Example:

~ $ which sudo
eshell/sudo is a compiled Lisp function in `em-tramp.el'.
~ $ alias sudo '*sudo $*'
~ $ which sudo
sudo is an alias, defined as "*sudo $*"

Some of the built-in commands have different behavior from their external counterparts, and some have no external counterpart. Most of these will print a usage message when given the --help option.

In some cases, a built-in command’s behavior can be configured via user settings, some of which are mentioned below. For example, certain commands have two user settings to allow them to overwrite files without warning and to ensure that they always prompt before overwriting files. If both settings are non-nil, the commands always prompt. If both settings are nil (the default), the commands signal an error.

Several commands observe the value of eshell-default-target-is-dot. If non-nil, then the default target for the commands cp, mv, and ln is the current directory.

A few commands are wrappers for more niche Emacs features, and can be loaded as part of the eshell-xtra module. See Extension modules.


Source an Eshell file in the current environment. This is not to be confused with the command source, which sources a file in a subshell environment.


Adds a given path or set of paths to the PATH environment variable, or, with no arguments, prints the current paths in this variable.


Define an alias (see Aliases). This adds it to the aliases file.


Return a file name without its directory.


Concatenate file contents into standard output. If in a pipeline, or if the file is not a regular file, directory, or symlink, then this command reverts to the system’s definition of cat.


This command changes the current working directory. Usually, it is invoked as cd dir where dir is the new working directory. But cd knows about a few special arguments:

  • When it receives no argument at all, it changes to the home directory.
  • Giving the command cd - changes back to the previous working directory (this is the same as cd $-).
  • The command cd = shows the directory ring. Each line is numbered.
  • With cd =foo, Eshell searches the directory ring for a directory matching the regular expression ‘foo’, and changes to that directory.
  • With cd -42, you can access the directory stack slots by number.
  • If eshell-cd-shows-directory is non-nil, cd will report the directory it changes to. If eshell-list-files-after-cd is non-nil, then ls is called with any remaining arguments after changing directories.

Scrolls the contents of the Eshell window out of sight, leaving a blank window. If provided with an optional non-nil argument, the scrollback contents are cleared instead.


Clear the scrollback contents of the Eshell window. Unlike the command clear, this command deletes content in the Eshell buffer.


Copy a file to a new location or copy multiple files to the same directory.

If eshell-cp-overwrite-files is non-nil, then cp will overwrite files without warning. If eshell-cp-interactive-query is non-nil, then cp will ask before overwriting anything.


Print the current local time as a human-readable string. This command is similar to, but slightly different from, the GNU Coreutils date command.


Compare files using Emacs’s internal diff (not to be confused with ediff). See Comparing Files in The GNU Emacs Manual.

If eshell-plain-diff-behavior is non-nil, then this command does not use Emacs’s internal diff. This is the same as using ‘alias diff '*diff $*'’.


Return the directory component of a file name.


Prints the directory stack. Directories can be added or removed from the stack using the commands pushd and popd, respectively.


Summarize disk usage for each file.


Echoes its input. By default, this prints in a Lisp-friendly fashion (so that the value is useful to a Lisp command using the result of echo as an argument). If a single argument is passed, echo prints that; if multiple arguments are passed, it prints a list of all the arguments; otherwise, it prints the empty string.

If eshell-plain-echo-behavior is non-nil, echo will try to behave more like a plain shell’s echo, printing each argument as a string, separated by a space.


Prints the current environment variables. Unlike in Bash, this command does not yet support running commands with a modified environment.


Toggle debugging information for Eshell itself. You can pass this command the argument errors to enable/disable Eshell trapping errors when evaluating commands, or the argument commands to show/hide command execution progress in the buffer *eshell last cmd*.


Exit Eshell and save the history. By default, this command kills the Eshell buffer, but if eshell-kill-on-exit is nil, then the buffer is merely buried instead.


Set environment variables using input like Bash’s export, as in ‘export var1=val1 var2=val2’.


The grep commands are compatible with GNU grep, but use Emacs’s internal grep instead. See Grep Searching in The GNU Emacs Manual.

If eshell-plain-grep-behavior is non-nil, then these commands do not use Emacs’s internal grep. This is the same as using ‘alias grep '*grep $*'’, though this setting applies to all of the built-in commands for which you would need to create a separate alias.


Prints Eshell’s input history. With a numeric argument N, this command prints the N most recent items in the history.


Browse the available Info documentation. This command is the same as the external info command, but uses Emacs’s internal Info reader. See Misc Help in The GNU Emacs Manual.


List subprocesses of the Emacs process, if any, using the function list-processes.


Kill processes. Takes a PID or a process object and an optional signal specifier which can either be a number or a signal name.


Eshell version of list. Allows you to create a list using Eshell syntax, rather than Elisp syntax. For example, ‘listify foo bar’ and ("foo" "bar") both evaluate to ("foo" "bar").


Create links to files.

If eshell-ln-overwrite-files is non-nil, ln will overwrite files without warning. If eshell-ln-interactive-query is non-nil, then ln will ask before overwriting files.


Alias to Emacs’s locate function, which simply runs the external locate command and parses the results. See Dired and Find in The GNU Emacs Manual.

If eshell-plain-locate-behavior is non-nil, then Emacs’s internal locate is not used. This is the same as using ‘alias locate '*locate $*'’.


Lists the contents of directories.

If eshell-ls-use-colors is non-nil, the contents of a directory is color-coded according to file type and status. These colors and the regexps used to identify their corresponding files can be customized via M-x customize-group RET eshell-ls RET.

The user option eshell-ls-date-format determines how the date is displayed when using the -l option. The date is produced using the function format-time-string (see Time Parsing in GNU Emacs Lisp Reference Manual).

The user option eshell-ls-initial-args contains a list of arguments to include with any call to ls. For example, you can include the option -h to always use a more human-readable format.

The user option eshell-ls-default-blocksize determines the default blocksize used when displaying file sizes with the option -s.


Run make through compile when run asynchronously (e.g., ‘make &’). See Compilation in The GNU Emacs Manual. Otherwise call the external make command.


Display Man pages using the Emacs man command. See Man Page in The GNU Emacs Manual.


Make new directories.


Move or rename files.

If eshell-mv-overwrite-files is non-nil, mv will overwrite files without warning. If eshell-mv-interactive-query is non-nil, mv will prompt before overwriting anything.


Alias to Emacs’s occur. See Other Repeating Search in The GNU Emacs Manual.


Pop a directory from the directory stack and switch to a another place in the stack.


Print the arguments separated by newlines.


Push the current directory onto the directory stack, then change to another directory.

If eshell-pushd-dunique is non-nil, then only unique directories will be added to the stack. If eshell-pushd-dextract is non-nil, then ‘pushd +n’ will pop the nth directory to the top of the stack.


Prints the current working directory.


Removes files, buffers, processes, or Emacs Lisp symbols, depending on the argument.

If eshell-rm-interactive-query is non-nil, rm will prompt before removing anything. If eshell-rm-removes-directories is non-nil, then rm can also remove directories. Otherwise, rmdir is required.


Removes directories if they are empty.


Set variable values, using the function set like a command (see Setting Variables in GNU Emacs Lisp Reference Manual). A variable name can be a symbol, in which case it refers to a Lisp variable, or a string, referring to an environment variable (see Arguments).


Set variable values, using the function setq like a command (see Setting Variables in GNU Emacs Lisp Reference Manual).


Source an Eshell file in a subshell environment. This is not to be confused with the command ., which sources a file in the current environment.


Show the time elapsed during a command’s execution.


Set or view the default file permissions for newly created files and directories.


Unset one or more variables. As with set, a variable name can be a symbol, in which case it refers to a Lisp variable, or a string, referring to an environment variable.


Wait until a process has successfully completed.


Identify a command and its location.


Print the current user. This Eshell version of whoami supports Tramp.

2.3.1 Defining new built-in commands

While Eshell can run Lisp functions directly as commands, it may be more convenient to provide a special built-in command for Eshell. Built-in commands are just ordinary Lisp functions designed to be called from Eshell. When defining an Eshell-specific version of an existing function, you can give that function a name starting with eshell/ so that Eshell knows to use it.

Macro: eshell-eval-using-options name macro-args options body…

This macro processes a list of macro-args for the command name using a set of command line options. If the arguments are parsed successfully, it will store the resulting values in local symbols and execute body; any remaining arguments will be available in the locally let-bound variable args. The return value is the value of the last form in body.

If an unknown option was passed in macro-args and an external command was specified (see below), this macro will start a process for that command and throw the tag eshell-external with the new process as its value.

options should be a list beginning with one or more elements of the following form, with each element representing a particular command-line switch:

(short long value symbol help-string)

This element, if non-nil, should be a character to be used as a short switch, like -short. At least one of this element and long must be non-nil.


This element, if non-nil, should be a string to be used as a long switch, like --long.


This element is the value associated with the option. It can be either:


The option needs a value to be specified after the switch.


The option is given the value t.

anything else

The option is given the specified value.


This element is the Lisp symbol that will be bound to value. If symbol is nil, specifying this switch will instead call eshell-show-usage, and so is appropriate for an option like --help.


This element is a documentation string for the option, which will be displayed when eshell-show-usage is invoked.

After the list of command-line switch elements, options can include additional keyword arguments to control how eshell-eval-using-options behaves. Some of these take arguments, while others don’t. The recognized keywords are:

:external string

Specify string as an external command to run if there are unknown switches in macro-args.

:usage string

Set string as the initial part of the command’s documentation string. It appears before the options are listed.

:post-usage string

Set string to be the (optional) trailing part of the command’s documentation string. It appears after the list of options, but before the final part of the documentation about the associated external command, if there is one.


If present, then show the usage message if the command is called with no arguments.


Normally, eshell-eval-using-options flattens the list of arguments in macro-args and converts each to a string. If this keyword is present, avoid doing that, instead preserving the original arguments. This is useful for commands which want to accept arbitrary Lisp objects.


If present, do not parse dash or switch arguments after the first positional argument. Instead, treat them as positional arguments themselves.

For example, you could handle a subset of the options for the ls command like this:

 "ls" macro-args
 '((?a  nil      nil show-all       "show all files")
   (?I  "ignore" t   ignore-pattern "ignore files matching pattern")
   (nil "help"   nil nil            "show this help message")
 :external "ls"
 :usage "[OPTION]... [FILE]...
  List information about FILEs (the current directory by default).")
 ;; List the files in ARGS somehow...