Arguments and outputs

Table of content

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

1. Arguments and quoting

Let’s take a closer look at some of the commands we’ve run:

Terminal - elvish

~> + 2 10 ▶ (num 12) ~> echo Hello, world! Hello, world!

In the first command, + is given two arguments, 2 and 10, separated by spaces – so far so good.

In the second command, echo is given Hello, world!. Following how we read the first command, this should also be two arguments. But this still achieved what we want – printing out Hello, World! – but how?

As it turns out, what’s happening with this simple command is actually not so simple:

  1. Elvish recognizes Hello, World! as two arguments and passes them to echo.

  2. The echo command receives two arguments and it joins them with a space before printing.

The consequence of this process can be better observed when you’d like to print multiple spaces:

Terminal - elvish

~> echo Hello, world! Hello, world!

Although we’ve used three spaces, all echo receives is two arguments Hello, and world!, so all it can do is joining them back with a single space.

1.1. Quoting

In order to pass spaces to echo, we can pass a quoted argument:

Terminal - elvish

~> echo 'Hello, world!' Hello, world!

A pair of single quotes delimits a quoted string, and tells Elvish that the text inside it is a single argument. In this case, echo only sees one argument containing Hello,   world (with three spaces).

You can use quoted arguments wherever you can use an unquoted argument. In fact, you can even quote the command name itself. This applies to all the commands we have seen so far:

Terminal - elvish

~> '+' '2' '10' ▶ (num 12) ~> 'randint' '1' '7' ▶ (num 3)

However, writing commands like this is unnecessary and unreadable. It’s better to reserve quoting to situations when it’s necessary, for example when the argument you’d like to pass has spaces.

1.2. Metacharacters

Another common reason to use quoting is when your argument includes metacharacters, characters with special meaning to Elvish. Some examples of metacharacters are #, which introduces a comment, and ( and ), which we’ll encounter soon. Quoting them stops Elvish from treating them as metacharacters:

Terminal - elvish

~> echo '(1) Rule #1' (1) Rule #1

We will learn more metacharacters as we learn more of Elvish’s syntax. As a rule of thumb, punctuation marks in the ASCII range tend to be metacharacters, except those commonly found in file paths, like _, -, ., / and \.

1.3. Double quotes

You can also create quoted strings with double quotes, like "foo" rather than 'foo'. It’s useful when the string itself contains single quotes:

Terminal - elvish

~> echo "It's a wonderful world!" It's a wonderful world!

Another difference is that double quotes allow you to write special characters using escape sequences that start with \. For example, \n inside double quotes represents a newline:

Terminal - elvish

~> echo "old pond\nfrog leaps in\nwater's sound" old pond frog leaps in water's sound

You can read more about single-quoted strings and double-quoted strings in the language reference page.

2. Working with command outputs

Let’s go back to our arithmetic examples:

Terminal - elvish

~> + 2 10 # addition ▶ (num 12) ~> * 2 10 # multiplication ▶ (num 20)

What if we want to calculate something that involves multiple operations, like 3 * (2 + 10)? Of course, we can simply run multiple commands:

Terminal - elvish

~> + 2 10 ▶ (num 12) ~> * 3 12 ▶ (num 36)

But this makes Elvish a really clumsy calculator! Instead, we can capture the output of the + command by placing it inside (), and use it as an argument to the * command:

Terminal - elvish

~> * (+ 2 10) 3 ▶ (num 36)

Now is also the time to explain the notation. It indicates that the output is a value in Elvish’s data type system. In this case, (num ...) is a typed number, although for the purpose of passing to *, (num 12) and 12 work identically. We will learn more in Value types.

2.1. Concatenating results

Other than using the output of a command as an argument on its own, you can also concatenate it to something else to build a bigger argument. For example, if we want to add some message explaining what the result is:

Terminal - elvish

~> echo 'And the result is... '(* (+ 2 10) 3) And the result is... 36

(For the purpose of string concatenation, (num 36) becomes just 36.)

When the output of a command doesn’t start with , it indicates that the output is a stream of bytes. For example, echo produces bytes:

Terminal - elvish

~> echo Hello! Hello!

Among Elvish’s builtin commands, some output values, while some output bytes. On the other hand, external commands can only output bytes; they don’t have direct access to Elvish’s system of data types.

Let’s finish this section by augmenting our “Hello, World!” example with the output of a useful external commands:

Terminal - elvish

~> echo 'Hello World! My name is: '(whoami) Hello World! My name is: elf

3. Command history

We have now worked with quite a few commands, some more simple, some more complex. Inevitably, you’ll want to run some commands that are either the same or similar to something you have run in the past. This is where Elvish’s command history feature is useful.

For example, if we rolled the dice once with randint 1 7 and want to roll it again, we can press :

Terminal - elvish

~> randint 1 7 elf@host HISTORY #34

We are now in a history walking mode. The basic operations work as follows:

  • Press to go back further, or to go forward.

  • If you can’t find your command, press Esc to exit this mode cleanly.

  • Pressing any other key accepts the current entry and do what the key usually does. For example, simply pressing Enter will accept the entry and run it. If you want to edit the command before running it, just start editing by pressing Backspace, Ctrl-W, and so on.

Walking the history like this is the best option if the command is recent. To find a more distant command, you can use the history listing mode instead by pressing Ctrl-R:

Terminal - elvish

~> elf@host HISTORY (dedup on) Ctrl-D dedup 21 echo $pwd 22 * (+ 3 4) (- 100 94) 31 make 32 math:min 3 1 30 33 randint 1 7

This mode works very similarly to location mode we saw in Your first Elvish commands. You can use and to select an item, and press Enter to insert to it. Similarly, you can type part of the command to narrow down the list:

Terminal - elvish

~> elf@host HISTORY (dedup on) git Ctrl-D dedup 7 git branch 8 git checkout . 9 git commit 19 git status

4. Conclusion

In this part, we dived into the inner workings of arguments and quoting, and learned how to capture and use the output of commands, and the distinction between value output and byte output. We also learned how to recall command history. These skills will help you build and use more complex commands and use them with ease.

Let’s now move on to the next part, Variables and loops.