Hacker News new | past | comments | ask | show | jobs | submit login
Rush: the ruby shell (heroku.com)
102 points by JoelMcCracken on Jan 11, 2011 | hide | past | favorite | 34 comments



Slightly embarrassingly (is this bad form?), I feel I should point out my really rather new and beta shell, Urchin:

https://github.com/Spakman/urchin/

I really like a lot about existing shells like Bash and Zsh, so it operates much like a standard shell - pipelines, job control, redirections, tilde expansion, aliasing, globbing, etc.

However, actual shell scripting feels really grim, so sometime in the near future (hopefully) it will be able to pipe into Ruby when needed. This will let you write Ruby directly on the command line, without escaping quotes and such and should make loops and custom shell functions much more fun for a Ruby programmer.

I also fancy experimenting with some things I've not seen in other shells - fuzzy filepath completion, per-project history, etc.

Any ideas are welcome!


Your vision sound much closer to what I was hoping Rush would be. I don't think it is bad form at all to mention it.

Not sure if this exists in Bash at the moment in the various/terminals and consoles but a searchable history of the commands I've run would be handy. Also, some easy way to get command history in segments (maybe allowing me to comment my command history and pull everything from one comment marker to the next) so I can make a repeatable shell script out of the correct set of commands once I get the commands right.

As another idea to play with, if there is a way (probably using github) to index shell recipes others have made and look them up on the command line, that could be fun. So I could do "urchin search 'postgres 9 snow leopard' and grab someone else's command recipe to build postgres if one is out there.


Nice one - I'm glad I'm not the only one where this type of shell sounds like a good idea!

I'd definitely like some clever types of history management. I've not looked too closely at those facilities in other shells (I would guess some of them have some cool ideas), but it sounds like we can certainly come up with some more!

I'm going to quickly lose track of this thread if I'm not careful. Do you use GitHub? Can you contact me there so we can stay in touch more easily, please?


Heh, I have the same story. Messaged both of you on Github, we should team up.

https://github.com/mharris717/lsl


Spakman, I'm very excited about this. And I say this as someone who's writing his own ruby shell/shell-complement. Mine is mostly intended to be invoked from Bash the way you'd invoke grep, though it can also be run interactively, where it behaves like irb. The one clever thing I did is allow you to avoid escaping by putting your ruby command after a # on the bash command-line. Bash then ignores everything after the #, and crush (my shell) grabs the last line in the bash history and evaluates the part after the #.

I will definitely be trying out your shell. If you're curious about mine (feel free to steal code, no promises that everything works as committed): https://github.com/afiler/crush


Cool! It looks like we also have similar ideas. I've been far too busy to get much time to look at any of the alternative shell projects this week, but I do intend to soon.

I was having similar thoughts about entering Ruby 'mode' (for want of a better term) with special characters. I'll be checking out your work soon.

All of these things make for some exciting stuff - I didn't realise others might be excited about them too!


Neat if you don't know the unix shell and you do know the ruby shell and I guess you work in a strictly ruby environment... but doesn't really make things easier, and many tasks may suffer performance wise when it comes to text processing compared to the standard unix shells & commands.


I know that this is a pedantic criticism, but isn't that convoluted "kill stray mongrels" command just a simple pkill? The first example is made excessively complicated as well (why not just grep -c)?

Certain things are definitely annoying to do with just the standard set of UNIX tools, but not knowing them well certainly won't help.


The first example is made excessively complicated as well (why not just grep -c)?

"grep -c" is great if you know it. The problem is it's a trick which only works for grep, and learning and keeping track of all of these tricks for every tool you use is a real pain. Never mind that "grep -c" will never be as flexible as wc.

It's more reliable to follow the Unix philosophy:

Write programs that do one thing and do it well. Write programs to work together.


"grep -c" is great if you know it.

This is a tough criticism, since "wc -l" is great if you know it too. And that, in the rush version, you need to use .lines on the result of .search() in order to get something you can call .size on to get the exact result you want (because it seems you can't just call .size on the result of .search(), I suspect that would just return a count of files where the string appears at least once).

In that vein, with a pipeline, you can look at each bit independently and reason about it. You can't reason about what .size returns (lines or bytes or whatever) without looking at what is immediately to the left of it (and then you have to know that .lines returns an array and that .size is returning the length of that array). And you have to know that whatever .lines returns actually has a .size method. wc -l always counts lines, no matter what its context is, because it's only ever dealing with text based input, never more complexly structured data like objects or arrays. This may or may not be what you want, but it does lend itself to wider (re)usability.


I think you've mistaken my argument as being against pipelines, but in fact I was arguing in favor of pipelines and against one-off tricks like "grep -c". Yes, "wc -l" needs to be memorized, but once, for everything you ever wish to count, as opposed to once for every command. In this respect, "grep -c" has the same problem as you pointed out concerning "lines".


Agreed.

   myproj['**/*.rb'].search(/^\s*class/).lines.size
And they say perl looks like line noise. The ratio of ispunct to isalpha in that line is 2:3.


the majority of that punctuation isn't part of the ruby syntax, to be fair.


Good point. These are idiomatic constructs that require familiarity in order to effectively use them.


Personally, since I am not an expert in shell commands and always work using python, I use IPython for all the shell needs. Works pretty awesome.

Here is how you go about it, for those interested:

http://ipython.scipy.org/doc/stable/html/interactive/shell.h... http://magazine.redhat.com/2008/02/07/python-for-bash-script...

Seems like, Rush is the ruby counterpart of what IPython is in python.


It's indeed comparable. I've used IPython for quite a while, and though it's great, I somehow fall back to using bash every time.

Conceptually, I like Python much more than shell script, but it seems I end up having to type and think more when simply using it as a shell.

When I get to the point where I actually need a real programming language such as Python to express what I want to do, I generally make a script and don't type it in the shell.


How about a Linux distro where Rush is used for startup and admin tasks, Gems are used to install everything, and besides the kernel and the VM, just about everything is in Ruby?

I know there was a RubyOS once, where they were trying to use Ruby in place of the shell.


I think this is pretty cool. I've wondered what a ruby shell would look like. I don't "get" bash at all, but I find ruby very natural. I've gotten better at writing bash one-liners for basic sysadmin tasks, however anything more complicated is hopeless. I've found it easier to write chef scripts to automate any server task than using bash.

The ability to easily execute commands on several remote servers is really appealing. At work, I only need to be able to ssh to 5 different servers and I frequently don't have a free screen terminal.


I think this is pretty cool. I've wondered what a ruby shell would look like. I don't "get" bash at all, but I find ruby very natural. I've gotten better at writing bash one-liners for basic sysadmin tasks, however anything more complicated is hopeless. I've found it easier to write chef scripts to automate any server task than using bash.

I'm no sysadmin, but I think you're doing it right as is. Scripting languages and DSLs like Chef are designed to be a better solution for those problems than shell scripts.

It's kind of funny, in a way. Perl was originally a scripting language for sysadmin tasks designed to replace shell scripts, that matured into a programming language, that influenced the Ruby programming language, from which we have a Ruby shell in which, presumably, we can write shell scripts again.


Capistrano (via the `cap shell` command) works pretty well for this.

http://weblog.jamisbuck.org/2006/9/21/introducing-the-capist...


Good work but just shy of being 3 years old (I posted about it on Ruby Inside in Feb 2008). A lot of old stuff resurfacing on HN recently it seems - perhaps we should be dropping the "N"? ;-)


Hacker reNews?


While I agree that bash and Co. are somewhat unintuitive and their syntax a little bit weird, the examples of commands Rush is supposed to make easier are intentionally made complex. That prevents me, as a potential user, from seeing how exactly would Rush appeal to me for administration and everyday tasks..


First I thought this was a replacement for irb, which would have been welcome.

Firstly, this will never have the adoption of bash, sit down on any Linux and you will be familiar. If you get used to shell and a normal human being which will have some delay context switching it will be a performance hit (same argument I'm sticking with qwerty for now)

Secondly, bash uses a domain specific language to tangle your fillesystem, simple things are simple, and unfortunately harder things Gerald blinked in the process. This comes with the overhead of learning some unintuitive things about ruby (blocks anyone?).


As an alternative to irb, you may be interested in ripl, http://github.com/cldwalker/ripl


Well it's an interresting project, although i fail to see the improvement over a regular bash/zsh shell.

> bash and ssh, we love you, but your era is past.

I'd love for that to be true, but let's see how their first example does compare against bash/ssh:

    local = Rush::Box.new('localhost')
    remote = Rush::Box.new('my.remote.server.com')
    local_dir = local['/Users/adam/myproj/']
    remote_dir = remote['/home/myproj/app/']
    
    local_dir.copy_to remote_dir
    remote_dir['**/.svn/'].each { |d| d.destroy }
versus

    remote=my.remote.server.com
    local_dir=/Users/adam/myproj/
    remote_dir=/home/myproj/app

    scp -r $local_dir $remote:$remote_dir
    ssh $remote "find $remote_dir -name .svn | xargs rm"
Okay so, bash/ssh is a tiny bit shorter, but that was to be expected.

Contrary to bash reputation, there is a lot less hard to type line noisy characters in the bash/ssh version than in the rush one, namely all the |[{ etc of the ruby version.

In my opinion, due to the reduced line noise, the bash/ssh version is a lot easier to read too. But it's less self-explanatory, in that scp/ssh commands are replaced by full names.

One might argue that the rush version is more conceptually elegant, because everything is objects, and you can streamline treatments this way, but :

- Even if this isn't true for bash, in practice it's the same thing, because connection strings are treated like hosts by all relevant programs, directory strings like directories by all relevant programs, etc. You lose in typing but not in usability

- This is in a context of a script where the authors considered it was better to actually have variables for everything, so that, i guess, the thing be better configurable, readable, and reusable. That's a good goal, but it's not always necessary.

Let's see how "raw" versions of the two compare :

    scp -r /Users/adam/myproj/ my.remote.server.com:/home/myproj/app
    ssh my.remote.server.com "find /home/myproj/app/ -name .svn | xargs rm"
versus

    root['/Users/adam/myproj/'].copy_to Rush::Box.new('my.remote.server.com')['/home/myproj/app/']
    Rush::Box.new('my.remote.server.com')['/home/myproj/app/**/.svn/'].each { |d| d.destroy }
The verboseness is of course worse when you don't declare variables. Let's be honest, i don't often declare variables for one off commands on the shell. I use auto-complete and i'm done with it. And for having typed this rush example by hand, i can assure you i'm not really ready to type that again anytime soon.

So i seriously doubt something like rush can replace something like bash/ssh. The benefits are likely to show up for bigger operations, where lots of people already use perl/python/ruby anyway because bash is a PITA for any serious programming, but bash still seems a lot more usable as a "shell", and i kind of understood this was the purpose of this.


For those interested in ruby shells, there's also a framework for building ruby shells: http://github.com/cldwalker/ripl


I can't imagine taking the effort to learn and use a new shell. That said, I'm always grateful when people try to end the chicken-egg problem.


Personally, I hate bash. Besides having syntax which is totally foreign to me, which I forget every after every time I attempt to learn it, it is extremely slow.

Besides that, I like structured data in the form of an object vs parsing everything from text.

However, this really is more of a unix criticism and less a bash criticism.


You use something like bash or zsh when it is convenient rather than to actually do anything with. If you are finding it slow use python, perl ,or something else to do your task; the real power of the shell comes from the easy access to all the unix tools that work well for their singular tasks. That power would be the main criticism I would find with the ruby shell, it seems so foreign and without access to the tools available (unless of course it is using them on the backend) but piping and other one off things would be interesting to see as examples because right now this shell looks like ruby with some libraries added in (sorry not a ruby programmer so I don't know the proper term)


I agree with your comment about structured data. Parsing everything from (unstructured) text is pretty backwards, it's more work and very error-prone.

But calling bash slow is kind of strange. What are you trying to do in a shell, that you can call it slow? A shell simply parses commands and dispatches them. For example, if you grep a 100GB file and it takes a long time the shell is not the bottleneck.


"it is extremely slow"

Why are people approaching a task which has a prerequisite of being speedy with the shell in the first place?

My only complaint about modern shells would be the lack of data structure support. I think it's slowly being remedied what with bash getting basic associative arrays.


so you liked or didn't like fish? or hotwire?


A ruby shell in a ruby based editor (Redcar) working on ruby projects might be productive as a mental context-shift free way to work.




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

Search: