Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A Unix shell written in Go
branch: master

README.md

Note:

On BSD, Linux or Mac OS X, you will need to apply a small patch before building Oh. To apply the patch copy exec_bsd.go.patched or exec_linux.go.patched, as appropriate, over the existing file in your Go source tree and run all.bash to re-complile Go.

Alternatively, you should be able to remove your OS from the list of build constraints in the files unix.go and other.go to build oh with job control disabled.

Oh now compiles and runs (but should be considered unstable) on Windows.

oh

Oh is a Unix shell written in Go. The following commands behave as expected:

echo "Hello, World!"
cal 01 2030
date >greeting
echo "Hello, World!" >>greeting
wc <greeting
cat greeting | wc   # Useless use of cat.
tail -n1 greeting; cal 01 2030
grep impossible *[a-z]ing &
wait
mkdir junk && cd junk
cd ..
rm -r greeting junk || echo "rm failed!"

Oh uses the same syntax for code and data. This enables it to be easily extended:

# The short-circuit and operator is defined using the syntax command.
define and: syntax e (: lst) as {
    define r = false
    while (not: is-null: car lst) {
        set r: e::eval: car lst
        if (not r): return r
        set lst: cdr lst
    }
    return r
}
write: and true false (echo "Never reached")

Oh is properly tail-recursive and exposes continuations as first-class values:

define label: method () as: return return
define continue: method (label) as: label label

define count: integer 0
define loop: label
if (lt count (integer 100)) {
        set count: add count 1
        echo: "Hello, World! (%03d)"::sprintf count
        continue loop
}

Oh exposes pipes, which are implicit in other shells, as first-class values:

define p: pipe

spawn {
    # Save code to create a continuation-based while command.
    define code = '(syntax e (condition: body) as {
        define label: method () as: return return
        define continue: method (label) as: label label

        set body: cons 'block body
        define loop: label
        if (not (e::eval condition)): return '()
        e::eval body
        continue loop
    })

    # Now send this code through the pipe.
    p::write @code
}

# Create the new command by evaluating what was sent through the pipe.
define while2: eval: p::read

# Now use the new 'while2' command.
define count: integer 0
while2 (lt count (integer 100)) {
    set count: add count 1
    write count
}

Oh's environments are first-class and form the basis for its prototype-based object system:

define point: method (r s) as: object {
    define x: integer r
    define y: integer s

    public get-x: method self () as {
        return self::x
    }

    public get-y: method self () as {
        return self::y
    }

    public move: method self (a b) as {
        set self::x: add self::x a
        set self::y: add self::y b
    }

    public show: method self () as {
        echo self::x self::y
    }
}

define p: point 0 0
p::show

Installing

go get github.com/michaelmacinnis/oh

License

Oh is released under an MIT-style license.

Motivation

Oh was motivated by the belief that many of the flaws in current Unix shells are not inherent but rather historical. Design choices that are clearly unfortunate in retrospect have been carried forward in the name of backward compatibility.

Like es, fish and rc, oh retains the look and feel of the Unix shell but does not aim for strict backward compatibility. Oh makes substantial improvements to the programming language features of the Unix shell by borrowing heavily from the Scheme dialect of Lisp. Rather than attempting to embed a Unix shell in scheme, oh was designed from scratch.

References and Other Shells

Fexprs:

1. Fexprs as the Basis of Lisp Function Application or $vau : The Ultimate Abstraction


First-class Environments:

2. First-class environments. Discuss. ;)


Unix Shells (Bourne Shell Family):

3. The Bourne Shell

4. Bash

5. The Korn Shell

6. Zsh


Unix Shells (C Shell Family):

7. An Introduction to the C shell

8. Tcsh


Unix Shells (Other):

9. Es: A shell with higher-order functions

10. The Fish Shell

11. Rc - The Plan 9 Shell


Alternative Shells:

12. A High-Level Programming and Command Language

13. Chris S. McDonald. fsh - A Functional UNIX Command Interpreter. Software - Practice & Experience 17(10): 685-700, 1987


Embedding the Unix Shell in an Existing Language:

14. L. M. Campbell and M. D. Campbell. An Overview of the Ada Shell. In USENIX Winter: 302-313, 1986

15. esh, the easy shell

16. Hell: A Haskell Shell

17. J. R. Ellis. A Lisp Shell. SIGPLAN Notices, 15(5):24-34, 1980

18. Using ML as a Command Language

19. Zoidberg - A Modular Perl Shell

20. The Perl Shell

21. Pysh: A Python Shell

22. Rush

23. The Scheme Shell


Shell History:

24. Shell History

25. The Thompson Shell

Something went wrong with that request. Please try again.