Live data from Hacker News

Ruby: A great language for shell scripts

lucasoshiro.github.io

201–210 of 368 posts

Re: Ruby: A great language for shell scripts

#201
post #119

It seems like a waste of precious syntax to dedicate backticks to running shell commands. What's between the backticks is not even portable; the commands rely on an operating-system-specific command interpreter. > puts `ls`.lines.map { |name| name.strip.length } # prints the lengths of the filenames Fantastic example, except for the commandment violation: "thou shalt not parse the output of 'ls'"! You really want to…

They have inherited the second biggest mistake of shellscripts; Requiring the user to manually check $? after each command. No thanks. Anything that doesn't have error handling enabled by default goes straight in the trash bin.

How is it supposed to know how you want your errors handled by default? Handling errors is the programmer's job.

Re: Ruby: A great language for shell scripts

#202
post #141

Earlier quoted context omitted.

I think the quality of a language for shell scripting is often secondary. What’s of greater significance is where it is at. I.e., does it have it already installed? The answer with Linux and Bash is almost always “yes”. Not so with ruby. The moment you start asking the user to install things, you’ve opened up the possibility for writing a program rather than a shell script. The lifecycle of a piece of software is alm…

This is indeed why I use Perl over Ruby. As long as it's not for a Window machine, a Perl script is deployed by copying it over and that's it.

That's true of Python and Perl as long as you keep using only the features built in in the core language (standard lib or whatever they call it.) The same applies to Ruby.

My scripting language is bash in at least 99% of cases. I used to program in Perl when I need some complex logic. I stopped using it some 10 or 15 years ago when I switched to Ruby for two reasons: I became more familiar with it than with Perl and it's easier to manage data structures whenever I need something complex or classes. That doesn't happen often in scripts but as I wrote, I use bash for all the normal stuff.

I use Python for the scripts that start an HTTP server because it has the http.server module in the standard lib and it's very simple to write handlers for GET, POST and all the other HTTP verbs. The last example was a script to test callbacks from an API. I just implemented two POST and PUT methods that print the request data and return 200 and a {} JSON. I think that to do the same in Ruby I would need to install the webrick gem.

Re: Ruby: A great language for shell scripts

#203
post #22

I love using Ruby for shell scripting, but there are also a ton of little nits I have to fix whenever I'm doing it. For example: Ruby has no built-in for "call a subprocess and convert a nonzero exit status into an exception", ala bash `set -e`. So in many of my Ruby scripts there lives this little helper: def system!(*args, **kwargs) r = system(*args, **kwargs) fail "subprocess failed" unless $?.success? r end And I…

> Ruby has no built-in for "call a subprocess and convert a nonzero exit status into an exception"

Since Ruby 2.6 you can pass `exception: true` to `system` to make it behave like your `system!`.

https://rubyreferences.github.io/rubychanges/2.6.html#system...

Re: Ruby: A great language for shell scripts

#204
post #9

I sometimes wonder why we don't see ruby used for shell stuff more often. It inherited most of the good stuff for shell scripting from Perl, and Perl took a lot of it's syntax from sh and sed and awk, so almost anything you can do in shell script you can do in ruby, but with an option of making it gradually less terse and more readable, while having sane variables and data handling from the start. Also ruby is great…

Instability. Ruby has not been the same language for very long. Migrating to 1.9 was a huge hassle for many firms. This may seem like a long time ago in tech years; but then there was Ruby 2.0; and shell scripts, meanwhile, have stayed the same the whole time. A secondary reason is that Ruby has been very slow for much of its life, which means that for situations where you need to run a huge stack of scripts -- init…

Mentioning 1.9 migration and ruby being slow? Python 2 to 3 was waaaaay worse and more negatively impactful, and equally slow (slower in most cases).

Ruby never had US market penetrative as perl or python, which were basically invented in the US, and congregated people from the academic realm. These things aren't decided based on meritocracy (no things ever are).

Re: Ruby: A great language for shell scripts

#205

No pipe (and I mean in parallel too) no love for me. Nice calling syntax though.

You can pipe with the `pipeline*` method of open3 which is part of the stdlib:

For example:

    require "open3"
    last_stdout, wait_threads = Open3.pipeline_r("cat /etc/passwd", ["grep", "root"])
    last_stdout.read # => "root:x:0:0::/root:/bin/bash\n"
    wait_threads.map(&:value).map(&:success?) # => [true, true]
https://ruby-doc.org/3.2.2/stdlibs/open3/Open3.html

Re: Ruby: A great language for shell scripts

#206

Being able to call external commands with backticks alone makes it better suited than Python for shell scripting.

IMO that feature snatches defeat from the jaws of victory because if the command fails (exit code >0) it doesn't raise an exception. Same issue with the system(...) method by default.

Re: Ruby: A great language for shell scripts

#207

Earlier quoted context omitted.

I think the quality of a language for shell scripting is often secondary. What’s of greater significance is where it is at. I.e., does it have it already installed? The answer with Linux and Bash is almost always “yes”. Not so with ruby. The moment you start asking the user to install things, you’ve opened up the possibility for writing a program rather than a shell script. The lifecycle of a piece of software is alm…

Not once have I worked anywhere where the people writing shell scripts didn't also control all of the boxen those scripts ran on.

I'm glad you never worked at a bank or an insurance company!

Re: Ruby: A great language for shell scripts

#208
post #42

Earlier quoted context omitted.

It wasn't that long ago that all the interesting infrastructure projects (vagrant, chef) were written in Ruby.

I'd argue that writing Chef in Ruby (and Erlang) was absolutely to its detriment. Yeah, it was popular. It was also a debugging and scaling nightmare (not that Opscode helped that any). In fact one of the reasons I rage quit megacorp for a second time was that I was required to use an Enterprise Chef instance that would log people out at random every 0-3600 seconds. I could throw plenty of deserved shade at my cowork…

I love ruby, and I'm using it for 18 years, but I've spent half a year on chef a decade ago and it was one of the worst wastes of time I had ever. Nothing to do with the language, everything to do with architecture of the thing.

Re: Ruby: A great language for shell scripts

#209
post #73

Earlier quoted context omitted.

Bundle it into a pex and distribute that. Its still way large but its easy to distribute.

Pex was also the solution I landed on after evaluating several non-container options for distributing a Python project to arbitrary Linux hosts. It works well but with one huge caveat: although you bring the stuff required to reconstitute the venv with you, you’re actually still using the system’s python executable and stdlib!! So for example if you want to make a project targeting all supported Ubuntu LTS versions,…

I wish an easy cross-platform PEX or shiv [1] were a thing. Binary dependencies are the biggest reason I prefer the new inline script metadata spec (https://packaging.python.org/en/latest/specifications/inline...) and `pipx run`. Luckily, they're pretty great. They have changed how I write Python scripts.

The way inline script metadata works is that your script declares arbitrary dependencies in a structured top comment, and a compliant script runner must provide them. Here is an example from a real script:

  #! /usr/bin/env -S pipx run
  # /// script
  # dependencies = [
  #   "click==8.*",
  #   "Jinja2==3.*",
  #   "tomli==2.*",
  # ]
  # requires-python = ">=3.8"
  # ///
pipx implements the spec with cached per-script virtual environments. It will download the dependencies, create a venv for your script, and install the dependencies in the venv the first time you invoke the script. The idea isn't new: you could do more or less the same with https://github.com/PyAr/fades (2014) and https://github.com/jaraco/pip-run (2015). However, I only adopted it after I saw https://peps.python.org/pep-0722/, which PEP 723 replaced and became the current standard. It is nice to have it standardized and part of pipx.

For really arbitrary hosts with no guarantee of recent pipx, there is https://pip.wtf and my venv version https://github.com/dbohdan/pip-wtenv. Personally, I'd go with `pipx run` instead whenever possible.

[1] I recommend shiv over PEX for pure-Python dependencies because shiv builds faster. Have a look at https://shiv.readthedocs.io/en/stable/history.html.

Re: Ruby: A great language for shell scripts

#210
post #207

Earlier quoted context omitted.

Not once have I worked anywhere where the people writing shell scripts didn't also control all of the boxen those scripts ran on.

I'm glad you never worked at a bank or an insurance company!

Why do you choose to write in a snarky way? Why does that make you glad? Why does this make you energetic?
Post reply on HN