Your first Elvish commands

Table of content

This article is part of the Beginner’s Guide to Elvish series:

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 refenrece 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 the magick 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, and cat for showing files. Both Unix systems and Windows provide ping 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) or certutil (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 from curl.

  • -o, along with the next argument elvish-HEAD.tar.gz, means that curl should output the result to elvish-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 writes elvish-HEAD.tar.gz to the working directory.

  • The shasum or certutil command reads elvish-HEAD.tar.gz from the working directory.

  • The tar command reads elvish-HEAD.tar.gz from the working directory, and writes elvish 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.