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: A great language for shell scripts
321–330 of 368 posts
Re: Ruby: A great language for shell scripts
#322Perl also satisfies all listed features
Re: Ruby: A great language for shell scripts
#323Earlier quoted context omitted.
Whoa, interesting... What version are you running? Here's my system: $ ruby -v ruby 3.3.1 (2024-04-23 revision c56cd86388) [x86_64-linux] $ time ruby -e '' real 0m0.122s user 0m0.102s sys 0m0.020s I found an old Reddit thread also hinting at bad start-up times: https://old.reddit.com/r/ruby/comments/aqxepw/rubys_startup_... .
Very old one :) Because its reliable. Version 1.8.7 here. I want controllable delays. I want controllable threads :) I want portability. Of course, if you need more peformance, you need to go for newer stuff.
Re: Ruby: A great language for shell scripts
#324No it’s not a great language. Too many ways to do the same thing. Not packaged by default on most Linux. Monkey patching makes things even harder to debug.
Re: Ruby: A great language for shell scripts
#325Earlier quoted context omitted.
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…
> Ruby does have a terse and intuitive syntax that would make for a good system shell. I learned enough PowerShell to be comfortable using it, and then picked up Bash and Ruby a few years later. I longed for a Ruby shell for a couple years.
Re: Ruby: A great language for shell scripts
#326Earlier quoted context omitted.
I think one of the advantages of a script is that you can quickly check what it is doing by simply opening it - an executable won't afford that.
Plus it can be run on any machine, while golang needs to be compiled for the specific architecture you'll be running it on. No messing about trying to get the right build.
Simpler than having to worry about Python versions, let alone dependencies.
Re: Ruby: A great language for shell scripts
#327Earlier quoted context omitted.
It wasn't that long ago that all the interesting infrastructure projects (vagrant, chef) were written in Ruby.
Shopify and GitHub are still mostly Ruby, right?
Re: Ruby: A great language for shell scripts
#328Earlier quoted context omitted.
> They have inherited the second biggest mistake of shellscripts; Requiring the user to manually check $? after each command. This isn’t true for Ruby nor shell scripts. In Ruby you have `system` or `Open3`. In shell scripts you: if my_command then on_success else on_failure fi Shellcheck even warns you of that. https://www.shellcheck.net/wiki/SC2181
You’re checking the return value of the command here. Do you wrap all calls in an if? I believe the author was talking about set -e (often used with -o pipefail), so that any unhandled error simply exits the script.
I don’t need to check the exit status of every command.
> I believe the author was talking about set -e (often used with -o pipefail), so that any unhandled error simply exits the script.
I have no idea how you could get that impression from the section I quoted.
How would setting one option once at the top of the script mean “Requiring the user to manually check $? after each command”?
Re: Ruby: A great language for shell scripts
#329Earlier quoted context omitted.
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
Can you easily chain these, though? (gzcat some.txt|grep foo|sort -u|head -10 etc?). Especially lazily, if the uncompressed stream is of modest size, like a couple of gigabytes?
last_stdout, wait_threads = Open3.pipeline_r(
["gzcat", "some.txt"],
["grep", "foo"],
["sort", "-u"],
["head", "-10"],
)
I'm not sure what you mean by lazily here, but internally[0] it creates real anonymous pipes[1] between the spawned processes, so the data does not go through the ruby process at all.[0] https://github.com/ruby/open3/blob/b8909222051b4103a19eba195...
Re: Ruby: A great language for shell scripts
#330Earlier quoted context omitted.
That was the reason Perl was what I switched too from bash when I was working on Solaris boxes; it was miles ahead of what was possible with bash AND it was already present. If I remember an older version of Python was also installed but by then Perl had already got me reeled in and I felt Python to be too "verbose" compared to Perl (I eventually changed my opinion when I got a bit more experience under my belt).
Interesting! I still find Python too verbose to stand in for shell scripts when Perl is available, with what I think is a decent chunk of experience.