Hacker News new | past | comments | ask | show | jobs | submit login
Cash: a cross-platform implementation of Unix shell commands in JavaScript (github.com/dthree)
173 points by _7sdg on Feb 23, 2016 | hide | past | favorite | 71 comments



I absolutely love msys2: http://msys2.github.io/

It comes with an easy to use installer and `pacman` package manager. Their repositories have lots of stuff already compiled to windows usage (the silver surfer, gnu global, etc).

Also, sshd works mostly out of the box. Ability to ssh to Windows box into a functional shell (not crippled cmd.exe) is a killer feature for me.


+1 for msys2 and pacman. I was able to compile rather obscure libraries with next to no effort thanks to this. It's simple and straight forward.

     pacman -S msys/apackage
I had very little linux experience in the past and was amazed by the wealth of libraries, tools available. Especially anything related to the Gnome project. This stuff should be more popular among Windows developers.


Thanks for mentioning this. I just started using Windows at home after a long break and defaulted to setting up Cygwin with cmder. Before that I used Arch Linux for a while so seeing that msys2 uses a port of pacman is intriguing. Could you (or anyone else for that matter) share more information about what it's like using this as opposed to Cygwin? Pros, cons, etc.


MSYS2 is a fork of Cygwin. The goal is to make it easier to compile software targeting Windows.

Some notable changes are:

- It has its own package repository, using PKGBUILDs on github. It can also be updated from within its own shell. Cygwin doesn't do this, for very important reasons, involving autorebase hell which MSYS2 is certainly still subject to.

- In their fork of cygwin1.dll, they removed support for symlinks (i.e. `ln -s` creates a full tree copy); and the /cygdrive/ root directory was replaced with / (just like the old/deprecated MSYS1).

- It has three startup links, in which gcc/ld/make and the like are all "symlinked" to different versions (e.g. targeting win32, targeting win64, or targeting MSYS2 itself). It makes it easier to compile software targeting windows. You should install separate -devel packages for each "environment".

- MSYS2 focuses on packaging dependencies that would be useful for compiling software targeting the Windows platform (e.g. libXYZ). In comparison, Cygwin is more of a mini-OS, packaging applications for general use (e.g. rsync, BIND, MySQL and X11). There is a lot of overlap, but many exclusive packages.

- MSYS2 is amenable to merging back with Cygwin, but, the patches they've made to cygwin1.dll can't be upstreamed. Cygwin proposed a new plugin system that would allow MSYS2 functionality within Cygwin, but, nobody has done the work to port MSYS2 to this new system. (maybe outdated information)


Autorebase hell is I hope a thing of the past. We made all of the executables involved in the running of pacman static (except msys-2.0.dll obviously, and some post-install scripts, but we try to remove those) and split the update procedure into two parts, "update-core" which handles updating the core of MSYS2 and pacman. The rest of the system update is then completed with "pacman -Su". We've had no reports of update failures since then.

We didn't remove support for symlinks, you can enable them in the MSYS env. var winsymlinks:nativestrict if you want. If symlinks didn't require special permissions, we'd enable them by default, but unfortunately they do. Maybe one day Microsoft will change their minds on this. I can only hope so. I guess you may have meant that we don't create the 'Cygwin special' symlinks that winsymlinks:native falls back to when it doesn't get permissions? Yes those are an interoperability disaster for MSYS2 when native programs read them.


One more important note about compiling software with MSYS2 is that the msys2 version of cygwin1.dll (i forget how it's renamed) obviously inherits the same license as cygwin1.dll. Cygwin1.dll is not LGPL. It is GPL. So any program you release compiled with MSYS2 inherits GPL virality, unless you pay Red Hat for a commercial Cygwin license.


This sounds like you're trying to scare people off using MSYS2 altogether with the GPL bogey man, and it misrepresents the point of MSYS2.

The 'msys2' software repository (as opposed to the 'mingw32' and 'mingw64' ones) contains things that link to msys-2.0.dll which is GPL, and yes it includes compilers and linkers that in turn generate new PECOFF objects that in turn link to msys-2.0.dll. This repository exists mostly as build scaffolding (Autotools, bash) to support building native Windows software (as exists in the other two repositories) and that is the real goal of MSYS2. If you want POSIX-y GPLed software on Windows, use Cygwin.

You are right to caution people on the naive usage of our msys2/gcc package, but you've made it sound like something much worse than it is.


By default the gcc packages in the mingw-w64-... groups don't link against that library.

You can explicitly include it if you need the POSIX compatibility parts missing from Windows, but most software doesn't.


Awesome! I don't use Windows except for gaming, but its good to know something like this exist. Just to fill up last information gap, is there any good terminal emulator on windows? I remember using something that came with Cygwin long time ago, and it was slow (I think I used Vim on that).


mintty comes with cygwin and msys2. It's the one I use. Other people have recommended other terminal emulators like ConEmu, but those have varying (subpar) levels of Unicode/color support.


I also use mintty. It's not great, but I haven't seen anything better (it seems that ConEmu is optimized for cmd.exe, not bash).

I'm really using `tmux` inside `mintty` so I have an emulation of tabs inside one terminal. It's not super-convinient, requires the user to setup his/her own .tmux.rc, but it gets the job done (still orders of magnitude better than cmd.exe or "even" powershell).


ConEmu "is optimized" for Windows. The problem is that cygwin is not optimized for Windows.

But there is cygwin connector: https://conemu.github.io/en/CygwinMsysConnector.html


doing about the same here but using only cygwin and cygrunsrv to run sshd

it work quite well, and yeah ssh to a windows box with a real shell is definitively something you want :)


Cygwin is a GNU port, not a small, random, and non-compliant[1] subset of POSIX shell utilities.

[1] http://pubs.opengroup.org/onlinepubs/009696699/utilities/con...


Utility trumps compliance.

That's not to say that standards are bad and shouldn't be followed. Just that, sometimes, you really don't need a 250 page committee-designed specification to get some basic shit done.


> That's not to say that standards are bad and shouldn't be followed.

(Open) standards-compliance becomes essential if we want our work to outlast us. Yes, we all know design by committee is horrible and gets nothing done. The solution is get rid of specs completely though. I don't trust "javascript developers" to have any sort of discipline. I'm sorry if this sounds like stereotyping but it just seems like a trend that we can't ignore.


Do you know what specs I used to write Cash? ^ look at the link two parents up.

Do you know how long I spent working on getting the specs right in Cash? Cash isn't perfect, but it took me months of "discipline" before I would let myself do even the initial release, which is `v0.1.0` btw.


Sorry, I didn't mean you when I said that. I meant our dependencies. We will revisit this topic when node js inevitably screws you and your project fails in mysterious ways with a new node update.


It would be mysterious if I didn't understand Node. Node hasn't mysteriously failed me yet. Looks like you're just sour with a little too little actual data.


It does sound like stereotyping. It also sounds very hostile to new ideas. You're essentially telling "javascript developers" to get off of your lawn.

I do actually agree with your point about compliance. It would be really cool if we had a POSIX-conformant set of shell commands written purely in JS, as an alternative to having to find and install compiled binary ports that run on our particular non-Unix systems. At least, it's an interesting idea.

Instead whenever something like this comes up, we see a bunch of grumpy systems programmers waving their fists in the air, as if C is the only language powerful enough to manipulate basic strings in the shell. Seems a bit silly to me when you think about it.


Sorry, I actually despise C. When all is said and done, Javascript is not a horrible language but Javascript developers have a horrible track record. I know it sounds like saying ($my_country is good but foreach $person in $my_country->people are bad.

However, why do we need to write shell commands in java script? I keep hearing about this new fancy systems language called rust which should be good enough for most projects. Why do we insist on using the same one language everywhere?


https://github.com/uutils/coreutils - in Rust.

https://github.com/aisola/go-coreutils - in Go.

https://github.com/search?l=Nimrod&q=coreutils&type=Reposito... - in Nim (didn't seem to take off)

You know how people write a to-do list, or a forum, or a blog to better learn a language? Some people write coreutils.


I was loosely involved in a project to reimplement all the Unix commands in Perl back around ~2000 or so.

Things seem to live on here:

https://metacpan.org/pod/PerlPowerTools


What exactly are you imagining is happening? People just want to use the languages they're familiar with. It does not harm you in any way. You're not going to be forced to start using JS in Bash.

"Why do we insist on using the same one language everywhere?" Who is this "we" you're talking about? Where is this "insistence"? It's not like there is some cabal out there that is organizing a campaign to rewrite everything in JS and also delete everything else. What does it matter to you that people started a new project, that re-implements functionality of a dear, favorite project of yours, without taking resources away from that dear, favorite project? These people, who are only wasting their own time, who would have never worked on your dear, beloved project anyway? If you don't want to use JS, just don't. Stop reading posts about JS.


What are you afraid will happen? That a JavaScript developer will get lazy and store function definitions in some globally-writable place, allowing untrusted logic to be injected into systems via some embarrassingly accessible route?

Because, yeah, that would be an awful thing to happen to shell utils.


But they are not written in cool languages therefore should be rewritten :(

In all seriousness, I am struggling a bit to see a point in porting everything to JS (beyond a weekend project because why not, let's learn something).

I might be a bit out of the loop since it's been a while that I worked on Windows (and have been using msys2 instead of cygwin back then), but how come DDL and native compiling are the issues in cygwin?

And the 1/15th of the size bit. It's largely simply negligible with hard drives (and even SSDs recently) nowadays.

No snark intended (well, other than the first line, sorry), just genuinely curious.


Well if Cygwin weren't a terrible mess, maybe we'd be using it more? It's universally reviled by most folks actually on the Windows platform.

The value of this is that it works easily, portably, and with minimal overhead.

By bigger question is, why does posix sh deserve to win? It's plaintext pipes approach is really frustrating in 2016.


> why does posix sh deserve to win? It's plaintext pipes approach is really frustrating in 2016.

I think that in many aspects plaintext has won. Many historical records of the last century will be or have already been lost, because of formats that nobody can read.

OTOH, plaintext is readable and supported by almost everything under the sun.


I think it is weird that people say "plaintext has won" when basically every data format under the sun is structured, no one keeps data unencrypted, and transport protocols have basically grabbed all the mindshare as storage protocols.

But keep in mind I think it is bad for pipes only.


I have no problems with powershell wanting to pipe "objects" but I still want a POSIX environment under Windows.

And about why POSIX deserve to win ?

For me it's about cross-platform command-line, I need to be able to run command-line tools that just behave the same under Windows, Mac OS X and Linux.

So far, Windows has ignored the command-line for years, and when they don't ignore it they change it every couple of years, from scripting hosts WSH to PowerShell to whatever else ...

Just sayin' it's hard to take Windows seriously when it come to the command-line environment, it is a huge mess.


> For me it's about cross-platform command-line, I need to be able to run command-line tools that just behave the same under Windows, Mac OS X and Linux

Then join my headache world of all 3 versions of bash doing subtly different things. We used to think our automation/deploy scripting could be cross platform if we used bash. Oh what heady and foolish days those were.


Porting existig software to JS is advantageous for a few reasons.

NPM makes cross-platform installation simple, easy, and scriptable by default.

Dependency management. The package manager supports both local and global installations, as well as the ability to manage multiple versions of a dependency where necessary. Not by convention, by default. Dependency hell simply isn't an issue in the JS ecosystem.

More secure. Scipt installation/management doesn't require root privileges. The runtime uses it's own sandbox. No matter how safe the underlying OS is, it's virtually impossible for a malicious script to break out and mutate memory/data outside of it's context. PwnToOwn competitions are frequently held to test, identify, and harden security.

Project hosting is trivial to setup. Package installation, upgrade, removal is supported by default.

Scripts aren't tightly coupled to the OS. So you don't have to import the entire universe to use them. For example, Cygwin or MiniGW not required.

Scripts don't require compilation. If you run into problems, it's trivial to open up the source and correct the issue yourself. Shorter iteration/feedback loops on OSS projects means more users are capable of contributing fixes and/or new features.

In short, all of the pain points that suck about native application development have been solved in the JS ecosystem.

Just the 'import the universe' point alone is enough to deter any dane dev from porting a *nix binary to Windows. Disk space isn't the concern, surface area for potential security issues, bugs, and the maintenance overhead of keeping an OS emulation layer updated are.

Javascript is a truly cross-platform solution.


> Huh? Okay - think Cygwin, except:

No GCC or compilers, which I would think is one of the biggest reasons most people use Cygwin? Cygwin isn't just shell commands, and surprisingly PowerShell doesn't suck as much it features some unixy commands. As well as others have mentioned Clink makes cmd.exe suck even less.


I only use cygwin to SSH into my irssi-box and that only because I have more control over how to looks than normal "cmd"

If you have something customizable, but not cygwin I'm all ears


Just for SSH? I use and love Bitvise on Windows, but I have no idea how customizable it is.


Using a terminal in windows was a horrible experience when I had to do it for a (fortunately brief) project a couple of years ago. But I think the real problem isn't the lack of a decent shell; there are already several shells out there that, while not as nice as their modern Unix equivalents, are at least usable. The bigger problem for me was the terminal emulator. Awful fonts, worse rendering, crappy copy/paste, limited size, no split screen or tabs, etc etc. It truly felt like being back in the 90's, although I'll bet that even in the 90's the Linux terminal emulator experience was better than Windows is now.


I have one word to say to that bet... no, wait... five... um... how many words is "]]]~3H^\x0b]]"?

But I suppose at least you only had to press one key to type it ;)



http://babun.github.io/ is wonderful.

ConEmu is a great container for a tabbed interface of Babun, PuTTY or powershell instances.


Babun seems to solve none of the issues that the original commenter mentioned.

  Awful fonts, worse rendering, crappy copy/paste, limited 
  size, no split screen or tabs
The screenshots on the Babun site show the same 90s-era looking shell container. ConEmu looks to have more features, but is similarly stuck in the Win-98 design aesthetic.


I have none of these issues. Fonts are nice and smooth (I'm using Consolas 10pt). Copy-paste works seamlessly. Limited size? In what regard? I can expand the window as I want vertically and horizontally and I have as much scrollback as I want (you configure it). ConEmu handles the splitting and/or tabs which works wonderfully.

Guess we're in opinion-mode at this point.

Can you provide an example of what you feel is a beautifully designed.. terminal container? We're still talking about the border of a shell are we not?

I must be missing something here.


What about Cmder then?

http://cmder.net/

It is slick, has nice copy/paste, can resize, do split terminals, and tabs.


Checkout ConEmu; it's like a combination of a decent term emu, tmux & dwm.


back in the win2k days i used to use the windows port of rxvt. it worked pretty well, though it didn't have splits or tabs.


well you are just replacing your dependency from cygwin to node.js

think of it, what is the utility to implement shell commands in a cross-platform way ?

only for Windows

You don't need an ES6 implementation of `ls` on Linux and Mac OS X, the tools are already there and yeah they are "ugly" compiled to native executable, but it is exactly what you want for shell commands

so you are basically trying to solve a Windows problem, but sorry you're doing it wrong

Windows problem is not about lacking shell commands, it's about lacking a POSIX environment

sure you want command line utilities like `ls`, but those are mainly useful when run inside a POSIX environment, and that is exactly the problem that cygwin have solved.

Now about some statements

"No ugly DLLs":

try to do a `ldd /bin/ls` on a Linux system you will see dependencies on `libc.so`, `libselinux.so`, etc. having tool like `ls` being dependent on `cygwin.dll` etc. is perfectly normal, nothing ugly about it

"Works in any terminal":

all the cygwin binaries can work inside a `CMD.exe` prompt, just add the "C:\cygwin\bin" path to your environment variables.

when you run Bash shell like Mintty, you also have access to the `CMD.exe` environment on top of the POSIX environment, for ex: you can call powershell scripts.

"Let's mix some Windows & Unix commands together"

`$ ipconfig | grep IPv4 | sort` works perfectly fine under Cygwin with bash

"but I only want certain commands"

maybe use package management, for ex you could use apt-cyg with cygwin, and do things like `$ apt-cyg install ncurses` or `$ apt-cyg remove ncurses`


V8 is a runtime.

Cygwin is an entire OS ecosystem of dependencies, tools, libraries. POSIX utilities are so tightly coupled to the OS, it's virtually impossible to use them with any degree of confidence without importing the entire universe. There's nothing 'perfectly normal' about such a poorly structured architecture.

JS dependencies are explicitly defined in a package's package.json so it's trivial to track a package's dependencies.

Likewise, one could create a powershell implementation in JS and -- barring windows-specific features -- Powershell scripts would 'just work' in a nix environment as well.

This package makes it trivial to port POSIX tools to Windows. What about greenfield development of utilities that need to work in both nix and Windows? Instead of building for one platform first then porting it to another (incl all the maintenance issues involved in maintaining separate forks in sync) why not use a truly cross-platform language from the start?

The Javascript ecosystem comes with it's own package management system.

Apt-get attempts to be 'everything to everybody'. It requires a monumental effort from the OSS community to maintain the different sources. Outdated packages are the norm making it harder for software maintainers to resolve bugs. Submitting new packages or publishing new versions of existing packages is a PITA. Etc...

NPM's source is centralized and provides a very useful online portal for: searching for packages by keyword and/or tags; publishing the Readme ad human-readable HTML (ie via Markdown); finding related links to the source control, issues, project pages; tracking downloads and development progress stats.

If you prefer not to publish to NPM the NPM directory, packages can be installed directly from GitHub, Bitbucket, etc.

Tapping the broader exosystem is easy for both users and developers.


I've used shelljs [0] a couple times now and it works great.

The big benefit is that you get cross platform support and anyone can contribute!

Overall, it just plays well with JS applications. If I have a bunch of domain-specific utils used in my application and I want to use em as I move some files around, using something like shelljs makes it very to mix and match.

I'm interested in giving cash a try, though. It's not immediately clear how it differentiates itself.

EDIT: I just scrolled to the bottom of the README and it has a section on the difference with shelljs. It appears that they have different goals.

[0] http://documentup.com/shelljs/shelljs


I'm quite fond of babun[0] when I have to do windows work. It packages up cygwin, zsh, oh my zsh and some other useful goodies into an easy to use package.

0: http://babun.github.io/


I've found ConEmu a reasonable substitute for xterm+tmux/dwm.

Cmd.exe isn't so bad after installing clink for readline behavior and learning a few idioms.

The only thing really bothersome is the lack of job control (partially obviated by ConEmu), which I didn't see in Cash.


ConEmu is good - Cmder makes it a lot easier to set up as it has clink already configured. Still a few inconsistencies, but I've got a nice setup with Cmder, gow, and a few other shell tweaks.


This is neat!

For Javascript we have the engine as V8 VM already, is it possible we can use javascript the way as python/bash(i.e. #!/bin/js) someday? that means ignoring the DOM/web related portion and make javascript a true client/server side script language, then it's really close to 'one language rules all'.


This works:

  #!/usr/bin/node

  console.log("hello");
mark it executable and enjoy.

Unless that's not really what you were getting at with your comment. If I misunderstood, sorry!


As the other poster notes, that's exactly what node is.


Nice! I've been using ShellJS (https://github.com/shelljs/shelljs) for this purpose (replacing a bash script with a cross-platform version). Any compelling reasons to use Cash over ShellJS, besides slightly better coverage of UNIX commands?


The readme covers this (check near the bottom).


I wonder about the "cross-platform" part. Does it work with Rhino, for example, or maybe even with the Windows Scripting Host JScript support? /s


I just started this in Nim in order to learn the language.


I general install git for windows and use the tools it comes with. Small simple and easy.


How about git bash from https://git-scm.com/downloads?


This is much better than I expected. Nice work!


Thank you. :)


Would be a good idea to write those in Go and just ship the runtime together with the binary IMO.


I would like to recommend GOW. It works pretty well for my needs.


Linux is enough to have Linux feel without the Windows' suck.


Some aren't that fortunate and have to work on Windows environments at work.


Others have spent years in UNIX land and still prefer Windows to Linux.


Oh no, how can you live like this ?


With Cash :)


And just plain cash. We get paid a lot of money to develop software on Windows.


We changed the title from "Cash – Linux feel on Windows without the suck" to a more neutral description from the article.


Okay thanks - no problem.




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

Search: