Hacker News new | past | comments | ask | show | jobs | submit login
A language that compiles to Bash and Windows Batch (github.com)
392 points by onecooldev24 on May 19, 2016 | hide | past | web | favorite | 142 comments

The idea is interesting, but ultimately the utility of this seems limited. The differences between windows and Unix are more than just the shell language involved; shell scripts are typically deeply intertwined with the system in question, to the point where it's often not the case that a bash script will even run reliably across different Unix systems, much less on windows. Also, you can already run bash on windows, so once again the problem doesn't seem to be the language per se. I can only imagine how difficult it would be not just to design a script that would work properly on both platforms, but to debug the cases where it didn't.

Also, as others have noted this language doesn't support redirection, which in my mind makes it practically useless beyond toy applications. I've written hundreds of bash scripts and I don't think any of them didn't make heavy use of pipes and redirection. I'm also not sure if the language supports running processes in the background, traps, magic variables like $!, extra options, subshells, file globbing, etc, all things that many real-world scripts use. Bash scripts often use many programs available on Unix systems as well, such as find, grep, readlink, xargs, and other things that aren't part of the language per se. Unless those are ported over too, writing useful scripts would be almost impossible.

Finally, I don't think the author has made a convincing argument that such a language is even needed, when languages like perl/python/ruby exist for when the task is complex enough to require a more powerful language. On the other hand, if the project is (as I suspect) purely for fun and interest, then by all means :)

The attraction for me is not about portability, it's about having a better language to write CMD script.

Even when you know you have Python available sometimes you still need to glue things together with CMD.

These days you probably want Windows Powershell. It's built on the .NET framework so it's pretty darn powerful and AFAIK is available by default on every modern WinOS.

Powershell _is_ great (I help run an OSS project written in Powershell), but it has a long start-up time. If you're doing it as a pre-build step for example, you don't want to add potentially seconds (!) to your build just to use powershell.

Do you use -noprofile? (you probably should for build steps, or else make sure all your build environments have a similar profile to yours) Then the startup time is usually much better - at least I haven't seen it going over some 100s of mSec.

Startup time used to be horrible in Windows 7 (v2, I think), but they improved it a lot since then. It starts instantly for me on my Windows 10 machine here.

Is there a linux or mac build of Powershell? After all this years hearing it is not that bad i would really love to try it a day or two

> sometimes you still need to glue things together with CMD

why? is there something cmd can do that python can't? one example is enough...

I don't use windows much anymore so there might be a better way to do this, but I'll propose a use case: Automating the installation of python on a fresh machine.

Fresh machine where and for whom? I doubt a simple batch script will get you very far (setup.exe exists for a reason...), and I doubly-doubt you would have enough overlap in the process that something that can convert the steps to bash would be an advantage. The only advantage I see for batsh is that it looks nicer to write in for the tiny subset of batch it supports. But then so is pretty much anything else -- it wouldn't surprise me if someone has already written a DSL in a well known language that can output to batch or powershell, we don't need a whole new language for this.

Ok, I'll try another use case: Political differences (specifically licensing). This project appears to be licensed under MIT, and python appears to be licensed under !MIT. I don't know what the implications are for the licensing of machine-produced shell code, or binary versions of Python, but I'm sure there are companies out there that would have opinions to favour one alternative over the other for reasons other than the technical merits of the choice.

Maybe. Python is under an MIT-like license, so you're fine, but if it were under e.g. the GPL you could still look to see if they have some form of runtime exception as GCC does. In any case it's rare for a company that's not well-established to care more about licensing that technical merit (and even any that do, the typical approach is to ask to buy a separate license if possible), and it's also rare that a company would use such a tool as this (created as a hackday project, in Ocaml, according to the author) rather than finding an alternative that meets their licensing criteria or just developing it in-house since it's not that big a tool and lacks a lot of useful capabilities like piping.

In that case you would use the chocolatey package manager bootstrapped by powershell to silently install Python.

It's a oneliner in powershell followed by choco install Python.

How are you going to install batsh though?

you don't need to install batsh. you maintain your code in batsh, compile to bat and have that up on your page as a download.

Even if you did distribute bat files online Windows would block downloading or running them by default so they are not a useful method.

Or, if you have developers, some on Windows and some on *nix, check in the batsh and its outputs.

You generate bat and sh files during the build, like deb or exe files.

It's not about can or can't I think. Examples: Language runtime can't be installed, system locked down with deepfreeze, not enough permissions..

Those aren't normally solved with scripting. However, any language with the ability to issue arbitrary system commands can accomplish everything a command line can.

Then how will batsh get installed?

Isn't the entire premise of batsh that it compiles to bat?

Why would you need to install batsh?

Who cares if Python can technically do it? If you have a CLI tool based around Bash, why would you want to rewrite it in Python and have to support it yourself and spend those man hours doing it?

The context of this article and all of these comments is writing new scripts, not rewriting old scripts. If you have a completed script that does everything you want, then none of this applies.

Because then you wouldn't have to write in Bash...

Or BAT. I can live (reluctantly) with Bash, but Windows batch file is just brutal.

I loved the idea.

Some years ago, I was making a project that many parts of the build process depended on simple file copies (that this can do right) and ImageMagik calls (that are the same in all OSes)

I ended having to keep writing the same scripts over and over again in Batch and Bash, it was quite a pain to maintain, and it was obvious that there had to be some way to do it automatically (port one to the other, or generate both).

This software has my situation as the perfect use case, when you need to script command line tools that exist in both platforms.

Why can't you use the windows versions of bash?

Isn't that only available on Windows 10, and only very recently?

There have been many attempts to bring Bash to Windows before WSL. Git for Windows ships with a Bash port based on Msys (IIRC).

So how to install it? Windows users are extremely lazy, they often just wait for a “click-and-run”.

I think it's a limitation more on the windows batch end. As mentioned, it's tricky for historical reasons.

Powershell would be closer to Bash, functionally speaking. An adapter between the two would be more functional- however doesn't satisfy the point of batsh, which assumes cleanish-builds of the OS in question.

Powershell introduces more complications, with functions like Invoke-WebRequest being given the alias "curl". At a minimum, you would get a type validation error, as Invoke-WebRequest by default gives back headers and other data as objects inside a larger object, not just the content string that curl.exe defaults to returning.

This should work in both bash and PS, with different results:

  > curl HTTP://example.com > file.html

Isn't that just what a compiled language would sort out for you? On Bash it'd compile to

curl HTTP://example.com > file.html

and on PowerShell it'd become

(curl HTTP://example.com).Content > file.html

There is an "adapter" between PowerShell and Bash - Pash (http://pash.sourceforge.net)

You've got to admire this and at the same time you can't help but see the shadow of two more letters on the end of its name...

Don't script it. Batsh it!

I feel like it was created just to make this sentence possible. Love it!

What about... lets take a "Shtab" at the problem.

Adopted by ASF as Apache Guano(tm).

The colonel interface is called 'bat' Guano, but then you have to answer to the Coca-Cola company.

Please give this person a medal.

That's not a bug; it's a feature.

I am the author of Batsh. Batsh is a toy language I developed 2.5 years ago in a hackathon. It was just for me to play with OCaml. Feel free to play with it at http://batsh.org/.

This deserves to be called out in the readme, if for nothing else than to limit the wild threads on display here and maybe head off some future wild threads.

It's a pretty interesting idea, more so when developed under the context of of a hackathon. Where did the idea come from?

Hey man this is cool, I posted this for you on hacker news.

The project hasn't been worked on in over a year also it isn't the language that is much different but the tools. Are you going to write grep on windows? If not the language really doesn't matter.

If the language has a string search command then it can implement its own, or it can delegate to grep on Linux and Findstr on Windows. Obviously in both cases it can't cover all that grep can do, but that likely isn't in scope. All I'd want is a tool that lets me maintain one build script for example.

Agree, you have to be careful these days not to bet on a dead horse. Or healthy and promising initially, but swiftly dead. I don't know that I need grep on windows or other powerful nix tools to find value in this. I'm not going to get cross-platform powerful scripts, but I need some simple batch file on windows to something, and god forbid I need to loop or increment or something, I'd probably rather use Jim's home brew language than batch...cuz it's that painful.

This is cool, but I hope the new Linux Subsystem in Windows 10 will propagate enough that everything can be written in bash

i will never understand why people fetishize that awful language.

I think it's your incorrect assumption that bash's popularity is due to it being a "fetish" for anyone. There aren't alternatives that are both better and more available / cross-platform / standard.

I agree its a crappy language, but remember, it's a shell, not a language. It serves a different purpose than being good for pure code, so saying something like "<your favorite scripting language here> is better than bash" doesn't hold a whole lot of water. It is way better than batch though.

"<your favorite scripting language here> is better than bash at the kind of tasks that bash is used for" would be a pretty substantial claim, though. (Unfortunately, it's almost never the claim that people are making. "X is better than bash at creating UIs/database lookups/OO/web programming"? Yeah, of course it is. Water's wet, too.)

It's significantly better than batch

Well sure, but these days PowerShell is what Windows people use for anything non-trivial.

Until your enterprise security people have a fit at something like PowerSploit [1] existing and turn on AllSigned via Group Policy. Then it's pretty much impossible to use PowerShell - edit, sign, test, edit, sign is quite painful with the current tooling (and that's even if you're "trusted" enough to get the codesigning cert). Not to mention that some of the scripts that Visual Studio uses aren't signed!

1: https://github.com/PowerShellMafia/PowerSploit

PowerShell took everything that was great about .NET and combined it with everything that was terrible about Bash. So we have, yet again, a difficult to understand language for shell scripting.

Why is it bad? I've been able to write some pretty great PS scripts to automate tasks. It's easier than firing up Visual Studio and writing a C# program I'd need to recompile if I ever want to change it.

It's very powerful but the syntax is step back 20 years:

    If ($Number -gt 0) 
That's just one example. There is a lot of really confusing stuff in powershell that's entirely unnecessary. There were going for some kind of Bash-shell familiarity which, oddly enough, most Windows developers don't even have.

I'd say the usage of -lt and the like is because angle brackets are used for piping data.

The shell is a mess of symbols making any sane programming language impossible. Instead of perhaps rethinking the "mess of symbols" issue they ruined the language instead.

Have you considered F#? Works well for scripting.

And PowerShell is an awful shell; it's great for script automation of windows, but as a shell, just no. Microsoft recognizes this, it's the reason a full Ubuntu bash shell is available in Windows 10.

> Microsoft recognizes this

MS also tried to improve PowerShell by installing the PSReadLine module by default.

Read https://github.com/lzybkr/PSReadLine for instructions on how to make PS a bit more usable.

The problem with PowerShell is its syntax, not the extra features of the shell environment. Trying to expose the .Net runtime to the command line is an admirable goal for a scripting language, not a shell. It comes down to this, PowerShell is a catherderal, bash and tools are a bizarre, and that's why they win IMHO. Personally the best shell for any Windows box is to install cygwin and treat it like a Linux box, and on Windows 10 just install Ubuntu and have a real Linux shell.

Windows servers are a dying breed and Microsoft knows it, they've lost that war and are quickly porting everything they can to run on Linux including their .Net runtime and Sql Server; they know they've lost the war, it's only a matter of time.

Most of my big complaints about syntax are related to the shell-ness of PowerShell. For example, when comparing things, I really want to use '<' and '>' rather than -le and -gt.

Generally though, the syntax is different but once you learn it, it's mostly fine and sometimes the text-based nature of Unix commands means you have to do a lot more reg-exing.

For example, compare these two:

    ps -ef | grep "chrome" | awk '{print $2}' | xargs kill

    ps -name chrome | kill 
Of course it's just a matter of preference, but I prefer the the PowerShell version.

Um... pkill chrome, still prefer bash/gnu tools. The bazaar has far more tools, you just have to find the right one.

> and sometimes the text-based nature of Unix commands means you have to do a lot more reg-exing.

That's a feature that has far more upside than downside.

I didn't know about pkill, thanks!

My point still stands. They are different but (IMHO) both excellent. Ubuntu on Windows may eventually reach parity with PowerShell but until then, PowerShell is worth knowing (especially if you follow Microsoft's advice and run servers without the GUI installed).

I agree it's worth knowing, I just don't like it. My prefferred avenue will be porting all .Net stuff to Linux servers and just getting rid of all Windows servers as it becomes possible. .Net is great, C# is great, Windows isn't and I'm glad to see Microsoft's new CEO isn't blind to that reality.

>bash and tools are a bizarre

You mean bazaar. Nice typo though.

bah, yea, thanks.

Really? I though PowerShell was designed primarily to replace cmd. Surely Windows people use actual programming languages for the majority of tasks with PowerShell/cmd for smaller scripting tasks.

It is significantly better than PowerShell.

and significantly worse too.

Jokes on you, they're going to end up baking bash commands into PowerShell.

Is there a way to get this as a precompiled Windows binary? I really want to give this a try, but I'm just sooo lazy and don't want to install OPAM if there's maybe a way around that.

ironically, the instructions there don't tell you how to get opam installed on windows either. i don't know the answer, but apparently [it's not trivial](https://github.com/ocaml/opam/issues/246)

If you just want to fool around there is a converter on the website.

Was hoping the website was a .it domain.

We'll just have to wait for people to ask "how do I make this shell script platform independent?" (batsh it)

already parked long ago

I was disappointed to see that the compiler was not written in batsh and therefore not self hosting. Seems like a missed opportunity.

Weird that it doesn't seem to support basename (1) and dirname (1) and their Windows equivalents (e.g. %~dp0%)

Quite a few of my scripts need to find files relative to the location of the script, or compute the path to an output file by replacing the extension of an input file.

As I read it, it is mainly a language that intends to "unify" bash and batch, but basename(1) is not so much a part of bash, but of POSIX, that is an executable in a POSIX environment, that can be called via bash.

However it does say "Batsh provided some "built-in" functions that will compile to platform-dependent code.". Arguably you could count basename and dirname under that.

The builtins are currently too limited. It looks like to get anything done you have to shell out to commands with call(), bash(), and batch() which leaves you with nice looking control structures surrounding a whole bunch of conditional code tailored for each platform. Path manipulation is an important missing feature. Some sort of array handling and filtering/sorting also needs to be abstracted.

I must have done it wrong. In the late 80s, I created a Windows batch-to-executable compiler called Builder (extending the language greatly, to the point of menus as language constructs). Made a decent living off it, too!

Consider posting in here then: https://news.ycombinator.com/item?id=11718197

I posted Batsh long ago, but it's totally impractical. The multiplatform PowerShell is the best option. Anyway, we need a new shell and NGS [0] looks like it. Neither zsh, nor Fish offer what a shell scripting language needs so that you don't have to use Python, Go, or another language for a slightly more complex stuff!

[0]: https://news.ycombinator.com/item?id=11734622

Since docker is on windows now, this should run script.sh in current directory pretty easily.

docker run -v %CD%:/opt -w /opt debian:jessie ./script.sh

A couple of slight nitpicks, but isn't this more like a translator? I understand a "compiler" to be that which condenses high-level structures down to more fundamental CPU-oriented structures (as opposed to an "interpreter" that takes the structures as presented). If you're compiling into Bash, or windows batch then you're converting from one high-level representation into another. Though you could debate whether these are "high level" whether they are technically or not. I will concede that this batsh language does indeed look a lot nicer than either - it seems to be of the "general purpose" style of C or Javascript rather than the more targeted style of either bash or batch - which is specifically for the domain of operating system scripting - I guess this might mean it's actually lower level. The whole thing is pretty cool though :-)

Cool stuff! Would have been useful for me when all I knew was C++! Unfortunately, I use Python for exactly this type of scripting. Oh and I also use it for stuff like Django, lxml, requests, wxPython, OpenCV, PyGame, NumPy, Reportlab ...

Looks nice but wouldn't you just use something like Python nowadays?

What if you want to build Python?

Oh, that' easy, you unpack the Python sources and start with:

But what is that? It's not written in Python. It can't be, because you don't have Python yet. It's a shell script.

It's not a hand-maintained shell script; it's written by expanding Autoconf macros (in the M4 preprocessing language) to shell code: essentially a compiler from another language to shell.

A cleaner language which does the same thing could, in principle, replace Autoconf.

A related use for such a language would be install scripts: perform complex actions to install some software, with minimal dependencies on what is already installed.

Writing your language's build system in itself shouldn't be any worse than writing your language's compiler in itself.

The GHC folks are rewriting their jungle of recursive Makefiles in Shake, a Haskell-based build system.

I think you only need the ability to build a cross compiler for this to work.

The "Why not Python/Ruby/Node.js/Lua" section lists 3 reasons the author developed this language...

The second point says “Functionalities like process piping are not convenient to use” but Batsh itself doesn’t support piping [1], a core feature of shell languages.

[1]: https://github.com/BYVoid/Batsh/issues/17

Bullet 1 says "None of them is preinstalled on all platforms", but OPAM isn't universally preinstalled either.

OPAM is only needed on the computer you develop the script. Actually you guys shouldn't be so lazy to just write something without reading the README.

You can build your scripts to a machine that has OPAM and distribute them to one that doesn't.

but you don't need opam to run the compiled scripts...

I love python, but python is not a shell, and it makes an absolutely awful shell replacement. Python is further from a good shell than bash is from being a decent programming language. Some scripts are good, I do use python for some kinds of shell scripts, but most of what I need bash for, python is not a good replacement at all.

But the goal of this is not shell replacement correct? It is a way to write scripts for both platforms. Python has great cross-platform support in that regard: http://hplgit.github.io/edu/ostasks/._ostasks002.html

Yes, you're right. Batsh isn't trying to be a shell replacement, but it is targeting the two shells that you're nearly guaranteed to find one of on any given computer.

I dunno if @zwieback was saying Batsh should target python, or if people should use python instead of Batsh, or something else, but neither of those first two suggestions makes a lot of sense to me.

Python's decent cross platform support doesn't really make it better for shell scripts, and while I use it for some shell scripts, I don't ever default to python. My comment was reacting to the "wouldn't you just", as though python is a natural default choice. In my experience, it's not a good default choice.

It's harder to debug python shell scripts, because you typically can't run individual lines, you typically can't cut and paste parts of it, you can't ever run system commands directly without wrapping it in a python module call, output might not display automatically, and you often have to install something that isn't already on the machine.

Perl is probably still the best in its class of being a decent language while allowing close interaction with shell commands. If I really needed to write a sophisticated shell script (try to avoid that), I'd probably go for Perl.

I'm mostly in agreement about Perl's status, but I'd rather take the small hit in verbosity for the niceness of the rest of Python rather than having to deal with Perl... Yeah it kind of sucks not having the backtick operator, but at least it's not too much of a hassle to do something like:

    from subprocess import check_output as sh
    files = sh(['ls'])
    print files
This has its limits but covers a lot of basic use-cases for the backtick. I think some people first see an alternate way of doing this in Python that's a lot more hairy, even if more flexible, but it doesn't have to be that way...

I don't think windows comes with python installation.

It also doesn't come with any of the tools bash is a glue for, about the only reason one uses bash. At least with Python I can write my own grep and so on, and piping isn't so bad with coroutines and generators.

I think you missed the point of this language. You write code in this language, and then you compile it to get Bash for Linux and Batch for Windows.

I get it, I just disagree with "it's not bundled" as a major disadvantage: neither is your script, and maybe neither is your argument to any `call()`, so you're going to be thinking about deployment in any case.

Could be a great tool for government/enterprise customers who want to avoid the whitelisting process involved around getting anything installed.

IT departments would laugh at you if you said you wanted to install python on their server...

Sure, there are probably use cases, though I'm biased to think there are better options for any specific one except perhaps the project creator's inspiring situation.

IT can laugh, I laugh back when java/flash/excel/browsers are already installed.

Windows has knock-off versions of several unix tools:

grep = findstr

cat = type

which = where

sort = sort

more = more

sudo = runas

Batsh already has some built-in functions which are, i assume, implemented on top of equivalent commands on either platform - for example, readdir() is implemented on top of either ls or dir. It seems plausible that more could be implemented on top of other pairs like these - for example, a searchfile() on top of grep and findstr, impersonate() on top of sudo and runas, etc. Perhaps what it really needs is an extension mechanism to make it easier to define such functions.

At least PowerShell has an ls alias for dir...

And no less!

I didn't know about where, being Windows "native". Thank you.

It also doesn't come with this "batsh" language...

You don't distribute the batsh language. You distribute what you build with it.

how is this top item? seems unfinished, unpolished, not very useful and very run of the mill as an achievement.

no easily found windows installer and has obscure dependencies whilst claiming it has none etc. etc.

I don't even see the ability to iterate through files or am I missing something?

Excellent idea. The only thing I thought was "why not PowerShell", but XP compatibility is probably the reason. (It exists but isn't preinstalled for that version.)

Powershell versioning is also a nightmare

I like the idea of compiling to bash from a much saner language even without Windows compatibility. With containers and slimmed-down OS like CoreOS Python and friends may not be available. Besides, for some tasks Python startup time is just unacceptable so using Bash could be a good option if not the awkward syntax to put it mildly.

"Bash is the assembly code of Unix?"

I was yearning for something like this literally just last night. Still am, tempted to give it a try.

Isn't it ironic to write this tool in a language that is not available on Windows[1]?

[1] "Windows support is comming soon. " https://ocaml.org/docs/install.html

OCaml is available on top of MinGW or Cygwin. The thing that isn't supported is OPAM (the package manager), and that's only for official support -- if you compile with MinGW or Cygwin you can get it working well enough for most tasks. You can actually get the compiler binaries from a precompiled versoin of the official distribution[1] or from a user-maintained distribution[2]. Additionally, you could just compile everything from source but that's more complex.

[1] https://protz.github.io/ocaml-installer/

[2] https://www.typerex.org/ocpwin.html

I love the fact that someone, somewhere needed this, and then someone, somewhere created it.

Me too. He created it at a Hackathon, it gets posted to Hacker News, and people here are still asking why. Because...

I've never tried but can't you already just run your node or ruby or whatever scripts on both Windows, Mac, Linux? Is there some reason targeting bash and batch is important?

From the README:

Why not Python/Ruby/Node.js/Lua

Yes you can use any of them as platform-independent glue code. But there are several disadvantages:

    None of them is preinstalled on all platforms (including Windows).
    Functionalities like process piping are not convenient to use.
    Hard to integrate with existing code written in Bash or Batch.
Those reasons are why I developed Batsh.

Both tend to exist on their respective operating systems by default, making it something that can run without further dependencies.

How should I pronounce the name? I read “batsh” as a homophone for “batch” [bæʧ], which is unfortunate. Is it supposed to be pronounced as two syllables [bæɂ.ʃ] or something like that?

Pronounced "bath". The s is silent.

Cygwin provides another way to run the bash shell on windows. It is really helpful with full features of some commands like 'find' 'sed' 'awk'.

There is also Pash: PowerShell + Bash (http://pash.sourceforge.net)

  @echo off
  set java=/usr/bin/java
that's not how it works. that's not how any of this works.

Where are you finding that?

At the time GNU/Windows became a thing recently (https://msdn.microsoft.com/en-us/commandline/wsl/about), the idea of Batsch turned obsolete to me.

And anyway I have been already been using crossplatform .fsx scripts for quite some time. KTHXBYE

This would be a candidate for the scripting language in redo

Paging @apenwarr

Opportunity to name this batshit wasted.

Relevant XKCD: https://xkcd.com/927/

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact