Skip to content

Gradually Upgrading Shell to YSH

Samuel Hierholzer edited this page Oct 29, 2024 · 2 revisions

The slogan of Oils is that it's our upgrade path from bash to a better language and runtime.

How exactly does that work? This page will give you an idea. Written in response to this lobste.rs thread.

Step 1: Run osh myscript.sh

Most shell scripts should run as is. The biggest difference may be better error messages when the script fails. (If you want gory details, see the Known Differences doc, but again these differences are small and rare.)

Optional: change the shebang line to something like #!/usr/local/bin/osh.

New Features

You can now start using features like var, const, setvar, and proc. You can just write them anywhere in the middle of your shell program!

: ${x=default}   # old-style shell code

const name = 'World'
var x = {greeting: "Hello $name"}  # A Python/JavaScript-like dictionary, with shell strings!

proc mycopy(src, dest) {        # named parameters!
  cp --verbose "$src" "$dest"   # You still need this quoting, which is ugly
                                # The next step allows you to get rid of it.
}

mycopy mytest /tmp              # a proc is just like a shell function

(Note: early in Oils' life, the project was aiming for automatic translation from bash to Oils. This is no longer a goal, although the work could be revived by an interested party.)

Run Tests If You Have Them

If you have a test suite for your program, run it with OSH, e.g. osh foo_test.sh.

Oils is currently able to run the git test framework, and it may run others. TODO: Add more to Shell Programs That Run Under OSH. (Oils should also have its own test framework in the future.)

Step 2: Add shopt --set ysh:upgrade To the Top of Your Program

This breaks a few things, but opens up more features.

See Shell Language Deprecations

The most common one is probably subshell:

# No longer valid
(cd /tmp; ls -l) 

shopt --set ysh:upgrade  # enable new YSH behavior (parsing and runtime)

# The new way to write subshells
forkwait { cd /tmp; ls -l }  

# Better for the cd case.  Saving and restoring state is done with blocks, not processes!
cd /tmp { ls -l }            

In exchange for changing your subshell syntax, you get Python-like expressions in if and while:

if (x > 0) {
  echo "$x is positive"
}

You don't have to remember how to type [ "$x" -gt 0 ] or [[ $x -gt 0 ]] or test "$x" -gt 0, or the differences between them. Oils has Python-like expressions.

Other changes:

  • One of the biggest changes is Simple Word Evaluation. This means you can now write cp --verbose $src $dest without the quotes.
    • You can also splice an array with cp --verbose @list_of_files $dest. This doesn't mangle your filenames!
  • If you had something like echo @mylabel in your shell script, you should change it to echo '@mylabel' (with quotes) to avoid invoking splicing. The @ is only special at the beginning of a word.

Step 3: Run with bin/ysh

This breaks more things, and is still subject to change. That said, I encourage you to try it and tell me what happens! Dozens of people have given feedback on the language and improved it.

Where To Send Feedback

Related

Clone this wiki locally