for x in *.jpg; do
gm convert $x ${x#.jpg}.png
done
to for x [*.jpg] {
gm convert $x (str:trim suffix $x .jpg).png
} for x in *.jpg; do
gm convert $x ${x#.jpg}.png
done
to for x [*.jpg] {
gm convert $x (str:trim suffix $x .jpg).png
}Now I use ble.sh [1] and Oh My Bash [2] and Atuin [3] and I love it.
This is really a field where I feel standardization is the better path. It's a similar feeling I get when I observe the vast array of notetaking apps I see made and think here is a place where it would be better to pick one FOSS solution and contribute.
[1] https://github.com/akinomyoga/ble.sh
I feel the opposite -- I use a commercial note-taking app for the same reason I use bash. It kinda sucks, but it's on all my devices, and the extra work imposed by the suckiness is more than made up for by familiarity and by not having to invest any energy to make it work seamlessly across my devices.
- You're not quoting your variables properly to prevent splitting and globbing.
- In case there are no jpg files in the working directory, Bash will put the pattern itself (*.jpg) into the $x variable. You need to explicitly check that the file in the variable actually exists before working on it.
Modern shells do not have these footguns.
Indeed that's one thing Elvish has better defaults that I forgot to mention in https://elv.sh/learn/scripting-case-studies.html#jpg-to-png...., and now I've added that, thanks :)
They made something new and non-detrimental and are sharing it with the world. It’s fine if it’s not something you’re going to use. I won’t either, but I’m failing to see the point of ridiculing their effort.
Your example seems unfair, too. It’s not like that is the only use-case on the homepage.
In other words, it's OK to type the first example on the command line and it'll work just fine (and if it won't, you'll be able to step in and fix). But running it as part of anything automated would be haphazard.
As I read this, the whole point is that you have something that feels quite familiar syntactically to a common shell, but sane. Kudos to the author!
foreach x [glob *.jpg] {
exec gm convert $x [regsub {\.jpg$} $x {}].png
}
(bonus, you can use `foreach x [glob *.jpg] y [glob *.png]` to iterate on more than one list at once)The truth is: if you choose to use something rarer than a ten-leafed clover, you better have massively good reasons to do so. Otherwise, there are already other languages with good subprocess integration; pretty sure Guile would do the trick too.
The "everything is a string" idea sadly turned out to not work that well for most people though, so Elvish has lists, maps, and first-class functions :)
Tcl lists are arrays (and kind of deques since https://core.tcl-lang.org/tips/doc/trunk/tip/625.md), dicts are the first-class maps we should have had since the beginning and apply allows to build closures around it.
I don't know about Elvish, but globs in bash aren't part of the loop syntax, they're their own thing, so this also just works:
for x in *.jpg *.pngMaybe you're not as traumatized by the thousand small cuts when writing traditional shell scripts as I, and that's fair :) However, I'd also invite you to read the rest of the examples, which go into the deeper advantages.
I'd also say that you don't have to "change my shell, have it deployed everywhere, and learn a new language" to start adopting Elvish! It's very easy to get Elvish (https://elv.sh/get/), and you can start using it on one machine, or for one script without "switching" 100%. Think of it as another tool you can use alongside whatever shell you are using (I'd also refer you to the other comment I posted: https://news.ycombinator.com/item?id=40317203).
https://elv.sh/learn/tour.html also has a big list of syntax comparison between bash and Elvish.
Re "cosmetic" - I'd agree that the extent syntax matters is more limited compared to semantics, but that limited extent can be a lot of the daily experience with a language! I've ported many bash scripts to Elvish and I still find it liberating to not have to write double quotes everywhere for my script to handle whitespaces correctly.
I see the basic concept for Elvish as PowerShell's language power, but with the more Unix-y sensibilities of traditional shells, plus, crucially, the human-friendly focus on rich built-ins for interactivity exemplified by fish.
I don't think a real-world implementation of that kind of idea is a 'merely cosmetic' innovation. There's real novelty in that synthesis. How to balance those inspirations is not obvious, and neither is how to fill the gaps between the big picture ideas and a usable tool.
Go use Elvish for a while and you'll see how much creativity has clearly gone into it. Hell, just browse the GitHub issues and you'll see.
It’s similar to Ruby.
I only realized the similarity with Smalltalk after that. I did learn a little Smalltalk many years ago but completely forgot about it, but it's possible that the knowledge was always somewhere in my subconscious brain.
var hosts = [[&name=a &cmd='apt update']
[&name=b &cmd='pacman -Syu']]
# peach = "parallel each"
peach {|h| ssh root@$h[name] $h[cmd] } $hosts
is hosts=( \
"host_a" "apt update" \
"host_b" "pacman -Syu" \
)
printf "%s\n" "${hosts[@]}" | xargs -L2 bash -c 'echo ssh root@$0 -- $*'
and ~> var project = ~/project
~> rm -rf $projetc/bin
compilation error: variable $projetc not found
is set -u
project=~/project
rm -rf $projetc/bin
bash: projetc: unbound variable
Now of course, there are a lot of edge cases in bash, especially around escaping and quoting, which are not handled in my crude examples.What annoys me with these new shells, is that they dont solve any issue of the real world.
Yes, your language is cute.
Yes it's safer and less error prone that bash, there's no denying that.
But it does not - and most likely will never - handle the trillion - arguably hacky - things that can are done in bash, because that would suddenly completely overbloat the language, multiply its complexity, etc.
Essentially that means it will always be some kind of niche toy with a couple of enthusiasts, while the rest of the world keep on sticking to bash, and overall nothing moved forward.
Now don't get me wrong, I'm all for writing toys. I also have hundreds of my own reimplementations of stuff just because it's fun to code, you learn stuff, etc. But I don't get the "I'm going to create a fancy website, build a community and post it on HN" vibe.
If you seriously think the shell scripting world need a refresher, then the real issue, and we all know it, is not the fanciness of the language. That's the fun part.
The real, actual work, is to provide a realistic path forward. Either by working on bash to improve its syntax to something more modern, maybe through `set` flags to keep backward compatibility. Or to write a transpiler to bash, but with safer and stronger semantics.
This is the actual path forward, and it's the _not fun_ part, it's grunt work, and nobody does it, meanwhile we can sit and use a shiny shell while complaining how bad and unsafe bash is.
I think we simply can't say for sure which path is better for the future of shells, and I'm quite excited by the fact that different projects are exploring different directions. I will just stick to the path I find best and won't try to convert you :)