summaryrefslogtreecommitdiff
path: root/src/content/tils/2021/01
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2025-03-31 21:51:40 -0300
committerEuAndreh <eu@euandre.org>2025-03-31 21:51:40 -0300
commit570ec471d1605318aeefb030cd78682ae442235b (patch)
tree51e17eabe37c6689f8799b55e6875c3480329a2c /src/content/tils/2021/01
parentMakefile, mkdeps.sh: Derive index.html and feed.xml from more static "sortdat... (diff)
downloadeuandre.org-570ec471d1605318aeefb030cd78682ae442235b.tar.gz
euandre.org-570ec471d1605318aeefb030cd78682ae442235b.tar.xz
src/content/: Update all files left to asciidoc
Diffstat (limited to 'src/content/tils/2021/01')
-rw-r--r--src/content/tils/2021/01/12/curl-awk-emails.adoc100
-rw-r--r--src/content/tils/2021/01/17/posix-shebang.adoc63
2 files changed, 86 insertions, 77 deletions
diff --git a/src/content/tils/2021/01/12/curl-awk-emails.adoc b/src/content/tils/2021/01/12/curl-awk-emails.adoc
index 880ddf1..875c655 100644
--- a/src/content/tils/2021/01/12/curl-awk-emails.adoc
+++ b/src/content/tils/2021/01/12/curl-awk-emails.adoc
@@ -1,28 +1,25 @@
----
+= Awk snippet: send email to multiple recipients with cURL
-title: 'Awk snippet: send email to multiple recipients with cURL'
+:neomutt: https://neomutt.org/
+:found-out-article: https://blog.edmdesigner.com/send-email-from-linux-command-line/
+:curl: https://curl.se/
-date: 2021-01-12
-
-layout: post
-
-lang: en
-
-ref: awk-snippet-send-email-to-multiple-recipients-with-curl
-
----
-
-As I experiment with [Neomutt][neomutt], I wanted to keep being able to enqueue emails for sending later like my previous setup, so that I didn't rely on having an internet connection.
+As I experiment with {neomutt}[Neomutt], I wanted to keep being able to enqueue
+emails for sending later like my previous setup, so that I didn't rely on having
+an internet connection.
My requirements for the `sendmail` command were:
-1. store the email in a file, and send it later.
-1. send from different addresses, using different SMTP servers;
-I couldn't find an MTA that could accomplish that, but I was able to quickly write a solution.
+. store the email in a file, and send it later;
+. send from different addresses, using different SMTP servers.
+
+I couldn't find an MTA that could accomplish that, but I was able to quickly
+write a solution.
The first part was the easiest: store the email in a file:
-```shell
+[source,shell]
+----
# ~/.config/mutt/muttrc:
set sendmail=~/bin/enqueue-email.sh
@@ -30,20 +27,24 @@ set sendmail=~/bin/enqueue-email.sh
#!/bin/sh -eu
cat - > "$HOME/mbsync/my-queued-emails/$(date -Is)"
-```
+----
-Now that I had the email file store locally, I needed a program to send the email from the file, so that I could create a cronjob like:
+Now that I had the email file store locally, I needed a program to send the
+email from the file, so that I could create a cronjob like:
-```shell
+[source,shell]
+----
for f in ~/mbsync/my-queued-emails/*; do
~/bin/dispatch-email.sh "$f" && rm "$f"
done
-```
+----
-The `dispatch-email.sh` would have to look at the `From: ` header and decide which SMTP server to use.
-As I [found out][curl-email] that [curl][curl] supports SMTP and is able to send emails, this is what I ended up with:
+The `dispatch-email.sh` would have to look at the `From:` header and decide
+which SMTP server to use. As I {found-out-article}[found out] that {curl}[curl]
+supports SMTP and is able to send emails, this is what I ended up with:
-```shell
+[source,shell]
+----
#!/bin/sh -eu
F="$1"
@@ -79,24 +80,30 @@ else
echo 'Bad "From: " address'
exit 1
fi
-```
+----
Most of curl flags used are self-explanatory, except for `$rcpt`.
-curl connects to the SMTP server, but doesn't set the recipient address by looking at the message.
-My solution was to generate the curl flags, store them in `$rcpt` and use it unquoted to leverage shell word splitting.
+curl connects to the SMTP server, but doesn't set the recipient address by
+looking at the message. My solution was to generate the curl flags, store them
+in `$rcpt` and use it unquoted to leverage shell word splitting.
-To me, the most interesting part was building the `$rcpt` flags.
-My first instinct was to try grep, but it couldn't print only matches in a regex.
-As I started to turn towards sed, I envisioned needing something else to loop over the sed output, and I then moved to Awk.
+To me, the most interesting part was building the `$rcpt` flags. My first
+instinct was to try grep, but it couldn't print only matches in a regex. As I
+started to turn towards sed, I envisioned needing something else to loop over
+the sed output, and I then moved to Awk.
-In the short Awk snippet, 3 things were new to me: the `match(...)`, `split(...)` and `for () {}`.
-The only other function I have ever used was `gsub(...)`, but these new ones felt similar enough that I could almost guess their behaviour and arguments.
-`match(...)` stores the matches of a regex on the given array positionally, and `split(...)` stores the chunks in the given array.
+In the short Awk snippet, 3 things were new to me: the `match(...)`,
+`split(...)` and `for () {}`. The only other function I have ever used was
+`gsub(...)`, but these new ones felt similar enough that I could almost guess
+their behaviour and arguments. `match(...)` stores the matches of a regex on
+the given array positionally, and `split(...)` stores the chunks in the given
+array.
I even did it incrementally:
-```shell
+[source,shell]
+----
$ H='To: to@example.com, to2@example.com\nCc: cc@example.com, cc2@example.com\nBcc: bcc@example.com,bcc2@example.com\n'
$ printf "$H" | awk '/^To: .*$/ { print $0 }'
To: to@example.com, to2@example.com
@@ -115,28 +122,27 @@ to@example.com,
$ printf "$H" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, " "); print tos[2] }'
to2@example.com
$ printf "$H" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, " "); print tos[3] }'
+----
-```
+(This isn't the verbatim interactive session, but a cleaned version to make it
+more readable.)
-(This isn't the verbatim interactive session, but a cleaned version to make it more readable.)
+At this point, I realized I needed a for loop over the `tos` array, and I moved
+the Awk snippet into the `~/bin/dispatch-email.sh`. I liked the final thing:
-At this point, I realized I needed a for loop over the `tos` array, and I moved the Awk snippet into the `~/bin/dispatch-email.sh`.
-I liked the final thing:
-
-```awk
+[source,awk]
+----
match($0, /^(To|Cc|Bcc): (.*)$/, m) {
split(m[2], tos, ",")
for (i in tos) {
print "--mail-rcpt " tos[i]
}
}
-```
+----
-As I learn more about Awk, I feel that it is too undervalued, as many people turn to Perl or other programming languages when Awk suffices.
-The advantage is pretty clear: writing programs that run on any POSIX system, without extra dependencies required.
+As I learn more about Awk, I feel that it is too undervalued, as many people
+turn to Perl or other programming languages when Awk suffices. The advantage is
+pretty clear: writing programs that run on any POSIX system, without extra
+dependencies required.
Coding to the standards is underrated.
-
-[neomutt]: https://neomutt.org/
-[curl-email]: https://blog.edmdesigner.com/send-email-from-linux-command-line/
-[curl]: https://curl.se/
diff --git a/src/content/tils/2021/01/17/posix-shebang.adoc b/src/content/tils/2021/01/17/posix-shebang.adoc
index 5f5b897..4e2fbe8 100644
--- a/src/content/tils/2021/01/17/posix-shebang.adoc
+++ b/src/content/tils/2021/01/17/posix-shebang.adoc
@@ -1,55 +1,58 @@
= POSIX sh and shebangs
-date: 2021-01-17
+:awk-1: link:../../../2020/12/15/shellcheck-repo.html
+:awk-2: link:../12/curl-awk-emails.html
-layout: post
+As I {awk-1}[keep moving] {awk-2}[towards POSIX], I'm on the process of
+migrating all my Bash scripts to POSIX sh.
-lang: en
-
-ref: posix-sh-and-shebangs
-
----
-
-As I [keep moving][posix-awk-0] [towards POSIX][posix-awk-1], I'm on the process of migrating all my Bash scripts to POSIX sh.
-
-As I dropped `[[`, arrays and other Bashisms, I was left staring at the first line of every script, wondering what to do: what is the POSIX sh equivalent of `#!/usr/bin/env bash`?
-I already knew that POSIX says nothing about shebangs, and that the portable way to call a POSIX sh script is `sh script.sh`, but I didn't know what to do with that first line.
+As I dropped `[[`, arrays and other Bashisms, I was left staring at the first
+line of every script, wondering what to do: what is the POSIX sh equivalent of
+`#!/usr/bin/env bash`? I already knew that POSIX says nothing about shebangs,
+and that the portable way to call a POSIX sh script is `sh script.sh`, but
+I didn't know what to do with that first line.
What I had previously was:
-```shell
+
+[source,shell]
+----
#!/usr/bin/env bash
set -Eeuo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
-```
+----
-Obviously, the `$BASH_SOURCE` would be gone, and I would have to adapt some of my scripts to not rely on the script location.
-The `-E` and `-o pipefail` options were also gone, and would be replaced by nothing.
+Obviously, the `$BASH_SOURCE` would be gone, and I would have to adapt some of
+my scripts to not rely on the script location. The `-E` and `-o pipefail`
+options were also gone, and would be replaced by nothing.
I converted all of them to:
-```shell
+
+[source,shell]
+----
#!/bin/sh -eu
-```
+----
I moved the `-eu` options to the shebang line itself, striving for conciseness.
-But as I changed callers from `./script.sh` to `sh script.sh`, things started to fail.
-Some tests that should fail reported errors, but didn't return 1.
+But as I changed callers from `./script.sh` to `sh script.sh`, things started to
+fail. Some tests that should fail reported errors, but didn't return 1.
-My first reaction was to revert back to `./script.sh`, but the POSIX bug I caught is a strong strain, and when I went back to it, I figured that the callers were missing some flags.
-Specifically, `sh -eu script.sh`.
+My first reaction was to revert back to `./script.sh`, but the POSIX bug I
+caught is a strong strain, and when I went back to it, I figured that the
+callers were missing some flags. Specifically, `sh -eu script.sh`.
-Then it clicked: when running with `sh script.sh`, the shebang line with the sh options is ignored, as it is a comment!
+Then it clicked: when running with `sh script.sh`, the shebang line with the sh
+options is ignored, as it is a comment!
Which means that the shebang most friendly with POSIX is:
-```shell
+[source,shell]
+----
#!/bin/sh
set -eu
-```
+----
-1. when running via `./script.sh`, if the system has an executable at `/bin/sh`, it will be used to run the script;
-2. when running via `sh script.sh`, the sh options aren't ignored as previously.
+. when running via `./script.sh`, if the system has an executable at `/bin/sh`,
+ it will be used to run the script;
+. when running via `sh script.sh`, the sh options aren't ignored as previously.
TIL.
-
-[posix-awk-0]: {% link _tils/2020-12-15-awk-snippet-shellcheck-all-scripts-in-a-repository.md %}
-[posix-awk-1]: {% link _tils/2021-01-12-awk-snippet-send-email-to-multiple-recipients-with-curl.md %}