Skip to content

Self Installation Scripts

Note

If you just ran a program with bash that printed a URL to this page, click the arrow below for more information on "What just happened?" below.

What just happened?

If you are reading this you probably just ran a YS program with bash. The first time you do that, the program installed the ys interpreter under the /tmp/ directory for you and then ran the program with it. Subsequent runs of the program will use that installed ys interpreter.

You may continue to run the program this way, but there will be a slight delay at the start each time while the run-ys auto-installer script is downloaded.

It is very easy to install the ys interpreter permanently on your system so that you can run the program with ys instead of bash.

$ curl -s https://yamlscript.org/install-ys | bash

See the YS Installation page for more information.


YS has a way to publish programs that people can run immediately without having installed the ys interpreter first.

Warning

See the Security Considerations below before using this technique.

Just begin your YS program with these lines:

#!/usr/bin/env ys-0
source <(curl '-s' 'https://yamlscript.org/run-ys') "$@" :

Then anyone can run your program using Bash with a command like this: bash script.ys arg1 arg2 ....

The first time they do so, the ys interpreter will be downloaded and installed under the /tmp/ directory.

The ys interpreter will be downloaded only once, and it will be used for all subsequent runs of the script.

Note

The curl command will still download and evaluate the run-ys Bash script on subsequent runs so the user will need to have internet access.

The program can also be run with the ys interpreter if the user installs it. In that case the Bash installer line will be ignored.

Since the program has a shebang line, it can also be run as a PATH command if the file is marked as executable.

Example🔗

Here's a small YS program that program that prints the ROT13 encoding of its arguments:

#!/usr/bin/env ys-0

source <(curl '-s' 'https://yamlscript.org/run-ys') "$@" :

alphabet =: set((\\A .. \\Z) + (\\a .. \\z))
rot13 =: cycle(alphabet).drop(13 * 2).zipmap(alphabet)

defn main(*input):
  say: str/escape(input.join(' ') rot13)

If we run it with ys:

$ ys rot13.ys I Love YS
V Ybir LF

If we run it with bash:

$ bash rot13.ys I Love YS
Installing the YS CLI '/tmp/yamlscript-run-ys/bin/ys-0.1.91' now...
Ctl-C to abort
See https://yamlscript.org/doc/run-ys for more information.

Installed /tmp/yamlscript-run-ys/bin/ys - version 0.1.91
--------------------------------------------------------------------------------
V Ybir LF

and again:

$ bash rot13.ys I Love YS
V Ybir LF

How It Works🔗

The program is both valid YS and valid Bash.

YS programs are required to start with a YAML tag like this:

!yamlscript/v0

But if they start with a shebang line like this:

#!/usr/bin/env ys-0

then the !yamlscript/v0 tag is optional.

When you run the program with bash, the shebang line is merely a comment and ignored by Bash.

The source line is a Bash command that reads and evaluates the contents of the <(...) process substitution file. The curl command inside downloads the run-ys script and installs the ys interpreter under the /tmp/ directory if it is not already installed.

It then execs the installed ys interpreter with your original program and any arguments you provided.

The source line is also a valid YS command. It calls the YS source macro which ignores all of its arguments (much like the comment macro does).

Use Cases and Security Considerations🔗

This technique is may be useful in situations where you want to share a YS program with people who are not yet familiar with YS.

Since the program is run with Bash which gets more Bash code from the internet, it is subject to the many security risks of running arbitrary code from the internet.

Caveat yamlscriptor!

A more secure way to distribute a YS program is to
[compile it to a binary executable](binary.md) and distribute the binary
instead.

There is at least one use case where this Bash technique is safe and useful:

You can easily run a YS program that you are developing with a particular version of the ys interpreter without having to install it first. Just use the YS_VERSION environment variable to specify the version you want:

$ YS_VERSION=0.1.91 bash my-program.ys arg1 arg2 ...

This might be useful for testing a reported bug with an older version of the interpreter, for example.

There may be other development and testing use cases for this technique as well. If you find one, please let us know!