81

I both love and hate writing Bash. I love that it's so streamlined for operating on files and working with processes (I agree with this popular question that it's way better in this regard than Python, Ruby, etc.), but I hate the syntax, particularly around conditionals, loops, etc.

(This is subjective, but I find it both confusing and annoying. E.g. $var when reading, but var when writing; writes silently fail if there are spaces around =; the double brackets in ifs when using regexp; double semicolons sometimes and single semicolons others; etc.)

As a huge fan of CoffeeScript, which compiles to JS, I've been wondering: are there any languages that have the aesthetic/syntax of languages like Python/Ruby/CoffeeScript but which compile and run as Bash instead of one of those other runtimes?

E.g. I'd love to be able to write mostly-Bash with just a bit simpler syntax:

$AGGREGATE_FILENAME = 'allfiles.txt'

if not exists $AGGREGATE_FILENAME
    touch $AGGREGATE_FILENAME

for $file in files/*
    cat $file >> $AGGREGATE_FILENAME

switch $1
    case 'test'
        run-tests
        echo 'Tests finished!'
    case 'deploy'
        echo 'Packaging...'
        mv foo bar/
        deploy-bar

This is a super contrived example, and the syntax is a strawman (mostly inspired from CoffeeScript but keeping the essential Bash notions of first-class commands, separated from variables, and loose typing).

Anyway, just a question and food for thought. I'd love to be able to write my scripts in something nicer than Bash. =) Thanks!

Community
  • 1
  • 1
Aseem Kishore
  • 10,404
  • 10
  • 51
  • 56
  • 3
    Have you considered looking at Perl? It has file globs, succinct existence checks (```print 'exists' if (-e $filename);```) and backtick execution. – tjdett Apr 20 '12 at 02:16
  • I haven't actually ever tried Perl. It came to mind as I was writing this question, but I've always assumed Perl was also full of incomprehensible syntax. =D I'll check it out — thanks! – Aseem Kishore Apr 20 '12 at 02:21
  • 2
    It can be. Fortunately you aren't required to actually *use* most of it yourself. – Ignacio Vazquez-Abrams Apr 20 '12 at 02:44
  • 1
    Say what you will about Perl, but it's a fine alternative to bash once your script exceeds about 15 lines. It's nearly guaranteed to be installed everywhere Bash is. – Greg Hewgill Apr 20 '12 at 02:58
  • Newer shells allow alot of leaway for backwards compatibility to older shells. You can simplfy your syntax be deciding to always use `[[ ..... && .... || ... ]]`, as an exaggerated, but sometime appropriate example. This style `[ .. ] && [ .... ]` goes back to the original bourne shell and some people feel compelled to use it for the portibility. Also note you can do any math inside of `(( a++ ))` or `cnt=$(( a++ ))` when you need cmd-substituion, admitly a bad example. Can't help with single ';' except to put each command on a separate line. ';;' are specific to case statements. Good luck. – shellter Apr 20 '12 at 03:56
  • I'm not aware of any interpreters that will get you from one language to bash. However, you can always use bash with Python using the "python << END" command line interpreter. This gives you the best of both worlds IMHO. You can simplify things by using bash for most of the work and when it gets to the messy stuff use python. Take a look at [stackoverflow post](http://stackoverflow.com/questions/2189098/embedding-short-python-scripts-inside-a-bash-script) and [python cmd line page](http://docs.python.org/using/cmdline.html#command-line) – secumind Jun 04 '12 at 18:01
  • Autoconf! Compiles to disgustingly-portable bourne shell! Makes writing complex scripts much easier, as well as helping you keep compatibility with all your Ultrix, Irix, Asterix, Getafix, and Sillytrix customers. – Nicholas Wilson Jun 06 '12 at 13:08
  • The advantage of a language that compiles to bash over just using an existing language like Ruby or Python is that bash is available on just about every linux system in existence, whereas other languages (or the libraries necessary to make them able to compete with bash in simple system tasks like executing commands and piping output) aren't. – Ajedi32 Jan 23 '15 at 20:30

8 Answers8

23

You could also try Batsh, which is a DSL (Domain-Specific Language) that compiles a C-syntax language to Bash (and Windows Batch).

knarf
  • 2,672
  • 3
  • 26
  • 31
BYVoid
  • 358
  • 4
  • 8
  • As far as I can tell Batsh project has been abandoned. Using opam version 1.2.2 I could not get this to install (compiler error) – benathon Nov 10 '17 at 10:37
15

Since I originally asked this question, two projects have been released which attack this problem and do a pretty good job. Both reimplement many/most Unix tools in more programming-friendly runtimes.

Plumbum is implemented in Python and looks pretty solid:

http://plumbum.readthedocs.org/en/latest/index.html

ShellJS is implemented on Node.js and also looks pretty good:

https://github.com/arturadib/shelljs

Exciting developments! I'm looking forward to trying them out. If you already have, it'd be great to hear your experiences in the comments. Thanks!

Aseem Kishore
  • 10,404
  • 10
  • 51
  • 56
14

I tried all of the above (results) and started powscript.

Differences powscript vs the tools above

  • extremely portable preprocessor (100% bash)
  • balances between coffeescript and bash
  • hasslefree portable all-in-one-file compiler/runtime, written in bash
  • loose transpiler: inline bash always possible
coderofsalvation
  • 1,764
  • 16
  • 13
8

Bish is another option:

https://github.com/tdenniston/bish

Shell scripting with a modern feel.

Bish is a lightweight language created to bring shell scripting into the 21st century. It gives programmers the comfort of modern syntax but compiles to Bash, resulting in good portability (in as much as Bash is portable).

masukomi
  • 10,313
  • 10
  • 40
  • 49
6

The problem is that the whole strings-based semantics of Bash is so horribly broken, it'd be pretty difficult to do something like CoffeeScript for Bash.

Since you probably don't need function-level interoperability to call functions that are written in Bash, you're better off using something entirely different. Perl is close to Bash in being nasty and full of shortcuts and weird syntax, but its semantics are mostly sound. Python is less comfortable for things such as launching processes but is far better for general systems programming, clean and easy to maintain. Python has great libraries and modules for everything; Perl even better.

Miguel Pérez
  • 506
  • 3
  • 7
4

I recently developed a language called BashClass which is Object Oriented, has type checking and allow multi-dimensional arrays. The language syntax is inspired by different programming languages.

Here's an example on how a List class is implemented (Full example here):

class List extends Object {
    var Object[] data = new Object[];
    var int size = 0;
    constructor List(){
        super_constructor();
    }

    function void add(var Object object) {
        data[size] = object;
        size = size + 1;
    }

    function void pop() {
        if(size == 0) {
            exception("Cannot remove element from an empty list");
        }
        size = size - 1;
        data[size] = null;
    }

    function int size() {
        return size;
    }

    function Object get(var int index) {
        if(index < 0 || index >= size) {
            exception("Cannot access element out of bound");
        }
        return data[index];
    }
}

Classes and multi-dimensional arrays in BashClass are converted to Bash 4.4 associative arrays. The language is at its first release and is open source on Github. Feel free to contirbute and suggest features.

CMPS
  • 7,733
  • 4
  • 28
  • 53
3

You might want to give ZSh a try, it has a lot of improvements to make your shell script more readable.

http://www.zsh.org

Jaromil
  • 76
  • 5
2

You might want to take a look into nscript, in which you can write shell scripts using javascript. All the common bash constructions are in there, like exit codes, pipes, stream redirects, argument expansion, globbing, prompt etc.

mweststrate
  • 4,890
  • 1
  • 16
  • 26