This article is part of the Beginner’s Guide to Elvish series:
-
Your first Elvish commands
1. Series introduction
Welcome to Elvish!
This series of articles will teach you the basics of Elvish, covering both its programming language and interactive features. We will be working through practical examples and see how Elvish can help you unlock your productivity at the command line.
You don’t need to be experienced in other shells, but you need to be familiar with basic operating system concepts like file systems and programs.
Before you start, make sure that you have installed Elvish. After
that, type elvish
in the terminal and press Enter to start Elvish
($
represents the existing shell’s prompt and is not part of what you type):
Terminal
$ elvish
All the examples below assume that you have started Elvish. Alternatively, you can use Elvish as your default shell and have Elvish launched by default.
2. Hello World!
Let’s begin with the classical ritual of printing “Hello, World!”:
Terminal - elvish
~> echo Hello, world! Hello, world!
You can follow this example (and many others) by typing the code and pressing
Enter. The ~>
part is Elvish’s prompt; you don’t need to type it.
Elvish code often follows a “command + arguments“ structure. In this
case, the command is echo
, whose job is to just
print out its arguments.
3. Builtin commands
The echo
command does a very simple job, but that’s just one of many commands
Elvish supports. Running other commands follows a similar “command + arguments”
structure.
For instance, the randint
command takes two
arguments a and b and generates a random integer from the set {a, a+1,
…, b-1}. You can use it as a digital dice:
Terminal - elvish
~> randint 1 7 ▶ (num 3)
(We’ll get to the ▶
notation later in this article, and the (num 3)
notation
in Value types.)
Arithmetic operations are also commands. Like the echo
and randint
commands
we have seen, the command names comes first, making the syntax a bit different
from common mathematical notations (sometimes known as
Polish notation):
Terminal - elvish
~> + 2 10 # addition ▶ (num 12) ~> * 2 10 # multiplication ▶ (num 20)
These commands come with Elvish and are thus called builtin commands. The reference page for the builtin module contains all the builtin commands you can use directly.
3.1. Commands in modules
Some builtin commands live in modules that you need to import first. For
example, mathematical operations such as the power function is provided by the
math
module:
Terminal - elvish
~> use math # import the "math" module ~> math:pow 2 10 # raise 2 to the power of 10 ▶ (num 1024)
We’ll learn more about modules in Organizing and reusing code.
3.2. Comment syntax
You may have noticed that we have annotated some of our commands above with
texts like # texts
:
Terminal - elvish
~> + 2 10 # addition ▶ (num 12)
The #
character marks the rest of the line as a comment, which is ignored
by Elvish. When typing out the examples, you can include the comments or leave
them out.
4. External commands
While Elvish provides a lot of useful functionalities as builtin commands, it can’t do everything. This is where external commands come in, which are separate programs installed on your machine.
Many useful programs come in the form of external commands, and there is no limit on what they can do. Here are just a few examples:
-
Git provides the
git
command to manage code repositories -
Pandoc provides the
pandoc
command to convert document formats -
GraphicsMagick provides the
gm
command, and ImageImagick provides themagick
command to process images -
FFmpeg provides the
ffmpeg
command to process and videos -
Curl provides the
curl
command to make HTTP requests -
Nmap provides the
nmap
command to test the security of websites -
Tcpdump provides the
tcpdump
command to analyze network traffic -
Elvish itself can be used as an external command, as
elvish
-
Your operating system comes with many of external commands pre-installed. For example, Unix systems provide
ls
for listing files, andcat
for showing files. Both Unix systems and Windows provideping
for testing network connectivity.
These example are all command-line programs, but even graphical programs often
provide command-line interfaces, which can give you access to advanced
configuration options. For example, you can invoke
Chromium
like chromium --js-flags=...
to customize internal JavaScript options (the
exact command name depending on the operating system).
4.1. A concrete example
Much of the power of shells comes from the ease of running external commands, and Elvish is no exception. Here is an example of how you can download Elvish, using a combination of external commands:
-
curl
to download files over HTTP -
tar
to unpack archive files -
shasum
(on Unix systems) orcertutil
(on Windows) to calculate the SHA-256 checksum of files
Terminal - elvish
~> curl -s -o elvish-HEAD.tar.gz https://dl.elv.sh/linux-amd64/elvish-HEAD.tar.gz ~> curl -s https://dl.elv.sh/linux-amd64/elvish-HEAD.tar.gz.sha256sum 93b206f7a5b7f807f6b2b2b99dd4074ed678620541f6e9742148fede0a5fefdb elvish-HEAD.tar.gz ~> shasum -a 256 elvish-HEAD.tar.gz # On a Unix system 93b206f7a5b7f807f6b2b2b99dd4074ed678620541f6e9742148fede0a5fefdb elvish-HEAD.tar.gz ~> certutil -hashfile elvish-HEAD.tar.gz SHA256 # On Windows 93b206f7a5b7f807f6b2b2b99dd4074ed678620541f6e9742148fede0a5fefdb ~> tar -xvf elvish-HEAD.tar.gz x elvish ~> ./elvish
(Note: To install Elvish, you’re recommended to use the script generated on the Get Elvish page instead. This example is for illustration, and assumes your OS to be Linux and CPU to be Intel 64-bit. We will see how to avoid making these assumptions in Variables and loops.)
Running external commands follow the same “command + arguments” structure. For
example, in the first curl
command, the arguments are -s
, -o
,
elvish-HEAD.tar.gz
and https://dl.elv.sh/linux-amd64/elvish-HEAD.tar.gz
respectively.
External commands often assign special meanings to arguments starting with -
,
sometimes called flags. In the case of curl
, the arguments work as
follows:
-
-s
means “silent mode”. You can try leaving this argument out to see more output fromcurl
. -
-o
, along with the next argumentelvish-HEAD.tar.gz
, means thatcurl
should output the result toelvish-HEAD.tar.gz
. -
https://dl.elv.sh/linux-amd64/elvish-HEAD.tar.gz
is the URL to request.
The second curl
command leaves out the -o
and its next argument, directing
curl
to write the result directly as output. This allows us to see the
checksum directly in the terminal.
You can find out what flags each external command accepts in their respective
manual. You’ll also find commands that accept flags starting with --
, and on
Windows, starting with /
.
5. The working directory
So far, we have run all the commands from the prompt ~>
. The >
part only
functions as a visual clue, but the ~
part indicates the
working directory of
Elvish. In this case, the special ~
indicates your home directory, which can
be /home/username, /Users/username, or C:\Users\username, depending on
the operating system.
Commands that work with files are affected by the working directory, especially
when you use a
relative path
like foo
(as opposed to an absolute path like /etc/foo
or C:\foo
). Let’s
look at our last example more carefully:
-
The first
curl
command writeselvish-HEAD.tar.gz
to the working directory. -
The
shasum
orcertutil
command readselvish-HEAD.tar.gz
from the working directory. -
The
tar
command readselvish-HEAD.tar.gz
from the working directory, and writeselvish
to the working directory.
You can change the working directory with the cd
command, and all these commands will work with files in that directory instead.
For example, let’s create a tmp
directory under the home directory and use
that as our working directory instead:
Terminal - elvish
~> mkdir tmp # on Unix ~> md tmp # on Windows ~> cd tmp ~/tmp> # Now run more commands...
You’ll notice that Elvish’s prompt has changed to ~/tmp
(or ~\tmp
on
Windows) to reflect the new working directory.
Our examples will continue to use the home directory for simplicity, but it’s recommended that you try them in a separate directory and keep the home directory clean.
5.1. Directory history
As you work with different directories on your filesystem, you’ll find yourself
using cd
very frequently to jump back and forth between directories, and this
can become quite a chore.
Elvish actually remembers all the directories you have been to, and you can access that history with the location mode by pressing Ctrl-L:
Terminal - elvish
~> elf@host LOCATION 18 ~/tmp 10 ~/elvish 10 ~/.local/share/elvish │ 10 ~/elvish/website │ 9 ~/.config/elvish │
Press ▲ and ▼ to select a directory, and press Enter to use it as your working directory.
You can also just type part of the path to narrow down the list. For example, to
only see paths that contain elv
:
Terminal - elvish
~> elf@host LOCATION elv 10 ~/elvish 10 ~/.local/share/elvish 10 ~/elvish/website 9 ~/.config/elvish 9 ~/elvish/pkg/edit │
6. Editing the code interactively
If you have tried all the examples on your computer, it’s possible that you have made some typos. (If you haven’t made any, pause and appreciate your typing skills.)
You are likely already familiar with these keys:
-
◀︎ and ▶︎ move the cursor one character at a time.
-
Alt-◀︎ and Alt-▶︎ move the cursor one word at a time.
-
Home and End move the cursor to the start or end of the line.
-
Backspace deletes the character to the left of the cursor.
-
Delete deletes the character on the cursor (or to its right if your cursor is an I-beam).
Elvish also supports some keys found in traditional shells:
-
Ctrl-W deletes the word to the left of the cursor.
-
Ctrl-U deletes the entire line, up to the cursor.
(See readline-binding
if you’d like to use
more readline-style bindings.)
7. Conclusion
Being able to run all sorts of commands easily is one of the greatest strengths of shells. When using Elvish interactively, most of your interactions will consist of simple invocations of various commands.
In this part, we learned the basics of running builtin and external commands and how they can be affected by the working directory. We also learned how to change the working directory quickly and how to edit your command.
We are now ready for the next part, Arguments and outputs.