I’ve long used the ODroid series for years now, but it seems like their standalone SBC offerings haven’t seen a refresh in a good while.
I also seem to be gravitating towards the NanoPi line of boards due to their large variety of form factors and capabilities: https://www.friendlyelec.com They even ahve some that are capable enough to be used as stand-alone routers
Printer tuneup, taxes, disk golf w/ a friend, configuring my home network + phone to connect to a VPS hosted wireshark VPN, running, and helping a friend move some things last minute
I love those kinds of programs! I create aliases and small shell functions all the time in this style. One of my favorites is a puts
function that basically evals in Ruby what I type. I often use it to do maths and date calculations. I know you can do this in shell, but I do so much Ruby that it is like a second language (third, after English?) for me.
function puts() {
ruby -r date -e "puts($*)"
}
$ puts Date.today + 10 # What day is ten days from now?
2022-03-19
$ puts "10 ** 3 / 9.0"
111.11111111111111
Very cool ! I always do this by opening a Python shell, but never thought about making a shortcut: thanks :D
I just open devtools in the browser, or maybe aa node repl instead, to each their own :)
One of my first utilities that I wrote was a dice, we wanted to play GURPS but didn’t have dice so I wrote one quickly. Back in the nineties there were no cellphones. I’ve written such things before and after but this one i always remember.
To follow the name of Ruby’s method to print to output. You can even see me calling it in the code puts($*)
.
Also, it not only evals the code, but prints its result.
I have a similar one:
$ datedate
Thursday 2022-03-10 13:09:58 Europe/Stockholm 2022
2022-03-10T13:09:58+01:00
1646914198
$ datedate +22 days -1month
Friday 2022-03-04 13:10:02 Europe/Stockholm 2022
2022-03-04T13:10:02+01:00
1646395802
$ datedate 1646395802
Friday 2022-03-04 13:10:02 Europe/Stockholm 2022
2022-03-04T13:10:02+01:00
but since I haven’t found anything as good as php’s strtotime(), it remains the only script that forces me to install php :( Source here: https://github.com/chelmertz/dotfiles/blob/master/bin/datedate
A coworker of mine created something like this in Rust:
$ date-math 'dec 30, 2021 + 2 weeks + 1 day'
2022-01-14
Note that GNU date can do this built-in:
% date -d 'dec 30, 2021 + 2 weeks + 1 day'
Fri Jan 14 00:00:00 CET 2022
Maybe https://github.com/hroptatyr/dateutils do the same job without PHP?
My aliases
alias rm="rm -i"
alias cdtemp="cd $(mktemp -d)"
alias pb="curl -F\"file=@-;\" https://envs.sh"
Favorite one is cdtemp
, great for quickly testing out stuff.
tired of the old and unintresting clear command?
Sorry, no I’m not. When I’m using a terminal, the last thing I want to do is wait.
In addition, my sense of humour has a dependency on a GUI toolkit and does not function in text mode.
ShellCheck makes the previously tedious search for that elusive missing backtick or doublequote super easy, barely an inconvenience:
- later in the series -
I also can’t really let go of backticks
I can’t help but think that switching from “``” to “$()” might help with string matching tasks…
Also, kinda confused why traps weren’t mentioned at all. Yes, using “-euxo pipefail” can sometimes make code fail unexpectedly, but combining them with traps makes scripts considerably more reliable and allows scripts to cleanup after themselves.
A rather silly example that tends to fail in predictable ways: https://github.com/cmonr/gh/blob/master/gh#L179
Also, kinda confused why traps weren’t mentioned at all. Yes, using “-euxo pipefail” can sometimes make code fail unexpectedly, but combining them with traps makes scripts considerably more reliable and allows scripts to cleanup after themselves.
For one it’s a work in progress, so I could still write something about traps. But more importantly, I don’t know what to write about traps, that hasn’t been covered in other bash guides already. Whereas the techniques I cover like for instance the .for .do .done macros or the zsh/bash starter are new or like the subshell function at least unusual enough to warrant mentioning. That not a single comment here has picked up on the new stuff, but that the discussion circles exclusively around the familiar -euo pipefail trope, is probably telling.
For one it’s a work in progress,
Oh, interesting. That’s actually not the impression that I picked up on, and could be part of the reason it’s been picking up a lot of heat.
Whereas the techniques I cover like for instance the .for .do .done macros or the zsh/bash starter are new or like the subshell function at least unusual enough to warrant mentioning.
That’s fair, though I do think that trap usage is still uncommon/unusual enough to warrent comment, but that’s also my opinion. Even outside of the ‘set’ discussion/heat, I always think that being able to cleanly fail is always desirable, but again, my opinion.
That not a single comment here has picked up on the new stuff
I think part of the problem might be that the list of pages was introduced as “Modern Bash Scripting”. I have a feeling that “Modern” is so overloaded, that different people entered the post with differing expectations, kinda like what would happen if someone read a list of suggestions starting with “Best, or “Minimal” or “Clean”.
If it was instead introduced as particularities, discoveries, or hacks, then maybe it would’ve gotten a better receiption?
Some people are also ~triggered by Shell and are eager to dump on anything they perceive as promoting it.
Exciting to see builtin JSON support on the way, although I’m probably going to stick to xh (like HTTPie but in Rust) as it’s really easy to add JSON data, query parameters, headers, etc.
Nice.
I had just learned about HTTPie, but was bummed to read it’s Python based. Figured there’s a Rust alternative.
i believe a similar result can be achieved using plain shell scripting. this is single bash pipeline, so it’s also usable in a single RUN
stanza in a Dockerfile
, without creating intermediate layers:
set -euo pipefail \
&& curl -fsSL https://... > file-contents \
&& expected_hash=... \
&& echo "$expected_hash file-contents" | sha1sum --check --quiet - \
&& (cat file-contents; rm -f file-contents) | wc -l
it works like this:
set
line is for ‘safer bash’ (search the web for details) and is a good default in general.curl
output in a file, aptly named file-contents
sha1sum
to check the file; pipeline aborts if there’s a mismatchsome more remarks:
mktemp
, trap
etcsha1sum
prints an error message like sha1sum: WARNING: 1 computed checksum did NOT match
(use --status
to suppress, but it’s generally good to see why things fail)So what’s really funny is that the idea for this script was to make it as simple as possible to use.
Over the years, I’ve observed people are a lot more willing to use trivial one-liners instead of multiline-inline blobs.
This is what the original idea was like:
url="..."; sum="...";
curl -Ls "${url}" > /tmp/file \
&& md5sum --quiet --check <(echo "${sum} /tmp/file") \
&& sh "/tmp/file"
This is good, but it, IMO, should be SHA256 or Blake2 instead, which are considered cryptographically strong unlike MD5.
Since this is just a validation script you could theoretically make it generic enough to process a handful of different hash types so that it’s more compatible.
I was just thinking about this, and had two thoughts:
-n md5
, -n sha256
, etc)Thought about adding other formats, but considering I was nerd-sniped, I had other things I intended to do today 😅
Definitely gonna read up on Multihash, as this is the first time I’ve heard of it.
You’re absolutely right, but most sites that I’ve come across that use the pattern only provide MD5.
I thought about adding a flag to specify the type of sum, but feature creep 😁
Just remember… if the script and the known-correct value for the hash are being obtained from the same site, this is unlikely to be protective. If someone is maliciously replacing the script, surely they will also replace the checksum sitting next to it.
This will probably flag plenty of errors where someone updates their script but not their checksum, though. Which is generally a good thing too, unless it teaches people to ignore the errors.
You’re absolutely right. This little script is insufficient if the threat model involves actors that are aware enough to update the sums along with the script, but that was definitely out of scope for this little excercise.
I don’t have any particular hopes for this little script, outside of I hope others find it useful and are made aware that running a script after being immediately downloaded could be made more secure.
Maybe just curl from ipfs.
As long as the key is the correct, you’ll always get the same data. About as good as a download link next to a hash.
Ooh, interesting. Hadn’t thought about IPFS as a solution.
Use case is a bit different/nuanced though. I wanted something where I could insert some sort of verification string prior to running that would be trivial for the author to also include as a part of a release.
Since IPFS doesn’t quite fit that description, it doesn’t feel like the right solution, but you did remind me that I should give it another look.
An improvement but afaics that still means ultimately trusting an external entity (ipfs infrastructure) versus a locally calculated checksum.
I haven’t looked very close at ipfs yet, it’s on my list as part of my archiving endeavours.
There’s no need to trust the “ipfs infrastructure”, just the client implementation. Content keys are generated from secure hashing the content itself.
But then the script needs an IPFS client, which is, too, vulnerable to this. Unless you mean hitting on a specific server, which can be manipulated as well (one of my friends actually did that, for a prank).
Unless the download somehow fail in the middle ? Take the following script:
#!/bin/sh
curl -o https://random.stuff/archive.tbz
tar -C $HOME/.cache -xJf archive.tbz
cp /$HOME/.cache/archive/blah /usr/bin
rm -rf $HOME/.cache/archive
Pretty simple, and downloading it from ipfs would work, but if the server chokes, and stops transmitting data at rm -rf $HOME
, then the script will just cleanup your home directory without warning. You got the script from the correct URL though.
So checking the hash (or best, signature!) after the download is complete remains a better option.
Might finally get into Rust, since it looks like I’ll be in a good spot to resume my embeded projects.
If things pan out well in the next few days, might even also get a real chance at finally learning control theory, and how to tune systems.
Apparently trying to search for a gap in my project archives.
Wanted to reference something from an earlier set of projects, but found out I might have accidentally deleted the data when experimenting with GPU Passthrough…
In-person robotics is back, so I’ll be volunteering for a day.
Outside of that:
10mi race, and evaluating OpenWRT performance on an RPi4, and evaluating Solidworks for CAD.
Tried F360, but the constant cloud-nudging anti-patterns are annoying.
Also: https://github.com/coderobe/hq
And for others looking for something a bit different, xml2 is a package that converts xml/html structures to a flat directory structure, and viceversa.
We’ll see. Outside of completing an in-person 10k, evaluation whether I want to pay for Fusion 360.
Really don’t like how cloud-heavy Autodesk is trying to make it, but having CAD, subtractive CAM, and even an API, make it very hard to ignore.
I’m really impressed with how that school administration handled this, and I never expected to think this.
Very nice writeup and execution!
I’ve actually considered doing this a number of times, bu the limiting factor that always makes me reconsider is that YouTube’s playlist management is absolute crap.
Only problem is that I don’t have any other good solutions, and a solution that kinda works is typically better than nothing at all so I dunno…