Analytics for notes
I don’t care very much but I would like to know roughly how much my notes pages are getting looked at. It looks like quartz supports a couple of analytics providers.
tinylytics
- Free as just a hit counter
- $50 / year
- Super easy to setup
plausible
- Open Source: https://plausible.io/open-source-website-analytics
- Maybe able to host on racknerd: https://racknerdtracker.com/
- Can also be hosted and paid for
Moving presentation to Cloudflare
Cloudflare wasn’t building my presentation because it was using a different version of yarn
. I got around this by setting an explicit yarn version in package.json
:
{
"name": "friend",
"type": "module",
"private": true,
"scripts": {
"build": "slidev build",
"dev": "slidev --open",
"export": "slidev export"
},
"packageManager": "yarn@1.22.22",
"dependencies": {
"@slidev/cli": "^0.50.0-beta.5",
"@slidev/theme-default": "latest",
"@slidev/theme-seriph": "latest",
"vue": "^3.5.12"
}
}
Eventually I would like to have everything on cloudflare because it’s fast and it’s free and doesn’t have any real limits right now.
Presentation Wrapup
A couple of things I wanted to do before the presentation gets shared out more widely:
- Add a note on the title slide about how to interact with it
- Add a letter at the end about what’s going on in this presentation, who I am, and how to contact me
- Setup a way to contact me
- Add super basic analytics
Contact me
I used jotform as a suuuper quick way to have a “contact me” form. Ideally I would like something that’s mine and fully customizable but this gets something up and going after 15 minutes of fussing with their online editor.
Analytics
I used tinylytics. It’s mostly just a hit counter but it gives me something to get an idea of how much/often people are looking at the slides (and my notes).
Add analytics to the vite project was easy but not intuitive. I had to add an index.html
and include just the head portion:
<head>
<script src="https://tinylytics.app/embed/<secret code>.js" defer></script>
</head>
xargs
So far in the missing semester book club I’ve been pretty familiar with all of the tools and techniques we’ve used (although I very frequently have to go lookup what all of the ! + <something else>
variables are in bash, !!
is the only one I know). But there is a command that I avoid and am slightly afraid of, xargs
(truthfully anytime I have a feel that it could be the right solution I end up writing a tiny script that does looping and stores things into variables). So today is my day to be at my growth-edge and figure it out.
- Some commands don’t read from standard input, they need arguments passed to them, but you want to use standard in and
xargs
fills in the gaps- Does the
find
command’sexec
argument function act like a built inxargs
?
- Does the
- Basic form
cmd1 | xargs cmd2
- The output fromcmd
is used as an argument forcmd
friend main
❯ echo hi | echo
Has no output but:
friend main
❯ echo hi | xargs echo
hi
Does has output
- Another example showing how the output gets all mushed together:
friend main
❯ seq 2 6
2
3
4
5
6
friend main
❯ seq 2 6 | xargs echo
2 3 4 5 6
- If args isn’t passed a command to run it automatically uses
echo
-t
says “Show me what command you’re actually running”
❯ seq 2 6 | xargs -t echo
echo 2 3 4 5 6
2 3 4 5 6
- Using xargs to do a ls on a series of folders from ls
~/workspace/play
❯ ls
one three two
~/workspace/play
❯ ls | xargs -t ls
ls one three two
one:
ella gretchen henry lion rene
three:
'a court of mist and fury' 'we are ok' 'wintering the power of rest in difficult times' 'yerba buena'
two:
aphrodite artemis athena hera zeus
Note: ls isn’t getting input for-each file. It’s getting a list of files at the end of it and then it knows what to do with them (command run: ls one three two
).
- We can also use arguments and flags on the command that
xargs
is running. This is runningls
WITH the-l
command
~/workspace/play
❯ ls | xargs -t ls -l
ls -l one three two
one:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:11 ella
-rw------- 1 nicole nicole 0 Nov 16 13:11 gretchen
-rw------- 1 nicole nicole 0 Nov 16 13:11 henry
-rw------- 1 nicole nicole 0 Nov 16 13:11 lion
-rw------- 1 nicole nicole 0 Nov 16 13:11 rene
three:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:12 'a court of mist and fury'
-rw------- 1 nicole nicole 0 Nov 16 13:12 'we are ok'
-rw------- 1 nicole nicole 0 Nov 16 13:13 'wintering the power of rest in difficult times'
-rw------- 1 nicole nicole 0 Nov 16 13:13 'yerba buena'
two:
total 0
-rw------- 1 nicole nicole 0 Nov 16 13:11 aphrodite
-rw------- 1 nicole nicole 0 Nov 16 13:12 artemis
-rw------- 1 nicole nicole 0 Nov 16 13:11 athena
-rw------- 1 nicole nicole 0 Nov 16 13:11 hera
-rw------- 1 nicole nicole 0 Nov 16 13:11 zeus
Here’s an example of getting a list of all users on the machine and putting them in alphabetical order then sticking the list all on one line:
❯ less /etc/passwd | cut -d: -f1 | sort | xargs echo
alpm avahi bin colord cups daemon dbus dnsmasq flatpak ftp geoclue git http lightdm mail nicole nm-openconnect nm-openvpn nobody ntp openvpn polkitd root rpc rpcuser rtkit systemd-coredump systemd-journal-remote systemd-network systemd-oom systemd-resolve systemd-timesync _talkd tss usbmux uuidd
-I
lets us set a placeholder for the output from the previous step and then use the output somewhere in the command that we’re passing. A common placeholder is{}
❯ ls | xargs -I {} echo "$(pwd)/{}"
/home/nicole/workspace/play/one
/home/nicole/workspace/play/three
/home/nicole/workspace/play/two
This command is running ls
then passing the result to xargs
which then stores the result into a sort-of variable called {}
and then runs the echo command which then gets the current working directory and outputs the current spot + the result from ls. Here’s what xargs
says when we ask it to show us what its doing:
~/workspace/play
❯ ls | xargs -t -I {} echo "$(pwd)/{}"
echo /home/nicole/workspace/play/one
/home/nicole/workspace/play/one
echo /home/nicole/workspace/play/three
/home/nicole/workspace/play/three
echo /home/nicole/workspace/play/two
/home/nicole/workspace/play/two
-
Why does this run the command once per line???
-
Using xargs to make files 1 through 100 in a directory
~/workspace/play
❯ mkdir numbers
~/workspace/play
❯ cd numbers
workspace/play/numbers
❯ seq 1 100 | xargs -I {} touch {}
workspace/play/numbers
❯ ls
1 12 16 2 23 27 30 34 38 41 45 49 52 56 6 63 67 70 74 78 81 85 89 92 96
10 13 17 20 24 28 31 35 39 42 46 5 53 57 60 64 68 71 75 79 82 86 9 93 97
100 14 18 21 25 29 32 36 4 43 47 50 54 58 61 65 69 72 76 8 83 87 90 94 98
11 15 19 22 26 3 33 37 40 44 48 51 55 59 62 66 7 73 77 80 84 88 91 95 99
This is runs the seq
command which generates numbers from a <start>
to an <end>
then passes the result of that through to xargs which uses the variable {}
which we then use as input to the touch
command which then creates a new file. 🙀
And then to clean up (without using substitutions ) I could do:
workspace/play/numbers
❯ ls | xargs -I {} rm {}
workspace/play/numbers
❯ ls
Orrrrr to make each of them into .md
files:
workspace/play/numbers
❯ ls | cut -d. -f1 | xargs -I {} mv "{}.txt" "{}.md"
workspace/play/numbers
❯ ls
100.md 16.md 22.md 29.md 35.md 41.md 48.md 54.md 60.md 67.md 73.md 7.md 86.md 92.md 99.md
10.md 17.md 23.md 2.md 36.md 42.md 49.md 55.md 61.md 68.md 74.md 80.md 87.md 93.md 9.md
11.md 18.md 24.md 30.md 37.md 43.md 4.md 56.md 62.md 69.md 75.md 81.md 88.md 94.md
12.md 19.md 25.md 31.md 38.md 44.md 50.md 57.md 63.md 6.md 76.md 82.md 89.md 95.md
13.md 1.md 26.md 32.md 39.md 45.md 51.md 58.md 64.md 70.md 77.md 83.md 8.md 96.md
14.md 20.md 27.md 33.md 3.md 46.md 52.md 59.md 65.md 71.md 78.md 84.md 90.md 97.md
15.md 21.md 28.md 34.md 40.md 47.md 53.md 5.md 66.md 72.md 79.md 85.md 91.md 98.md
-n
lets us take n-items at a time and do something with them. This can’t be used with-I
because-I
is basically-n 1
with variable support on top
workspace/play/numbers
❯ seq 1 10 | xargs -I {} touch {}.md
workspace/play/numbers
❯ ls
10.md 1.md 2.md 3.md 4.md 5.md 6.md 7.md 8.md 9.md
workspace/play/numbers
❯ ls | xargs -tn 2 echo
echo 10.md 1.md
10.md 1.md
echo 2.md 3.md
2.md 3.md
echo 4.md 5.md
4.md 5.md
echo 6.md 7.md
6.md 7.md
echo 8.md 9.md
8.md 9.md
And here’s using the -n
flag in a kind of interesting way:
workspace/play/numbers
❯ ls | xargs -tn 2 mv
mv 10.md 1.md
mv 2.md 3.md
mv 4.md 5.md
mv 6.md 7.md
mv 8.md 9.md
workspace/play/numbers
❯ ls
1.md 3.md 5.md 7.md 9.md
Because we’re taking 2-at-a-time we can use those arguments as the first and second arguments to mv. (This is a wild example and no one would ever actually do THIS but they would do this idea)
-P
is the max number of processes- The
exec
argument tofind
is slow which is why you might choose to usexargs
instead of it (also note that theexec
flag uses{}
as its substitution)
Find all of the markdown files and just print out single line with each file:
~/workspace/play
❯ tree
.
├── books
│ ├── a court of mist and fury
│ ├── highlights.md
│ ├── we are ok
│ ├── wintering the power of rest in difficult times
│ └── yerba buena
├── gods
│ ├── aphrodite
│ ├── artemis
│ ├── athena
│ ├── gossip.md
│ ├── hera
│ └── zeus
├── numbers
│ ├── 10.md
│ ├── 1.md
│ ├── 2.md
│ ├── 3.md
│ ├── 4.md
│ ├── 5.md
│ ├── 6.md
│ ├── 7.md
│ ├── 8.md
│ └── 9.md
├── secret-thoughts.md
└── squishes
├── ella
├── gretchen
├── henry
├── lion
└── rene
5 directories, 27 files
~/workspace/play
❯ find -name "*.md" | xargs echo
./books/highlights.md ./numbers/4.md ./numbers/1.md ./numbers/8.md ./numbers/10.md ./numbers/5.md ./numbers/9.md ./numbers/2.md ./numbers/6.md ./numbers/3.md ./numbers/7.md ./secret-thoughts.md ./gods/gossip.md
A nicer ls
One thing I had setup on my mac is aliasing ls
to eza
. A quick install and an alias that looks like
alias ls="eza --icons"
A nicer cat
bat
is new to me but oh-so-nice for getting syntax highlighting.
alias cat='bat --theme="Catppuccin Mocha"'
Linux annoyance
On my mac I have a bunch of global hotkeys that I depend upon:
- Bring up terminal
- Alfred
- Move windows - left, right, full screen
- Clipboard history
Missing Semester Lecture 2 homework
xargs
As we covered in the lecture
find
’s-exec
can be very powerful for performing operations over the files we are searching for. However, what if we want to do something with all the files, like creating a zip file? As you have seen so far commands will take input from both arguments and STDIN. When piping commands, we are connecting STDOUT to STDIN, but some commands liketar
take inputs from arguments. To bridge this disconnect there’s thexargs
command which will execute a command using STDIN as arguments. For examplels | xargs rm
will delete the files in the current directory.Your task is to write a command that recursively finds all HTML files in the folder and makes a zip with them. Note that your command should work even if the files have spaces (hint: check
-d
flag forxargs
).If you’re on macOS, note that the default BSD
find
is different from the one included in GNU coreutils. You can use-print0
onfind
and the-0
flag onxargs
. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.
I modified this slightly since I’ve been playing with a folder of markdown all morning:
~/workspace/play
❯ find . -name "*.md" -print0 | xargs -0 echo
./books/parts i didnt like.md ./books/highlights.md ./numbers/4.md ./numbers/1.md ./numbers/8.md ./numbers/10.md ./numbers/5.md ./numbers/9.md ./numbers/2.md ./numbers/6.md ./numbers/3.md ./numbers/7.md ./secret-thoughts.md ./gods/gossip.md
~/workspace/play
❯ find . -name "*.md" -print0 | xargs -0 zip -r archive.zip
adding: books/parts i didnt like.md (stored 0%)
adding: books/highlights.md (stored 0%)
adding: numbers/4.md (stored 0%)
adding: numbers/1.md (stored 0%)
adding: numbers/8.md (stored 0%)
adding: numbers/10.md (stored 0%)
adding: numbers/5.md (stored 0%)
adding: numbers/9.md (stored 0%)
adding: numbers/2.md (stored 0%)
adding: numbers/6.md (stored 0%)
adding: numbers/3.md (stored 0%)
adding: numbers/7.md (stored 0%)
adding: secret-thoughts.md (deflated 32%)
adding: gods/gossip.md (stored 0%)
And if we take a look at the zip:
❯ unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
0 2024-11-16 14:36 books/parts i didnt like.md
0 2024-11-16 14:26 books/highlights.md
0 2024-11-16 14:26 numbers/4.md
0 2024-11-16 14:26 numbers/1.md
0 2024-11-16 14:26 numbers/8.md
0 2024-11-16 14:26 numbers/10.md
0 2024-11-16 14:26 numbers/5.md
0 2024-11-16 14:26 numbers/9.md
0 2024-11-16 14:26 numbers/2.md
0 2024-11-16 14:26 numbers/6.md
0 2024-11-16 14:26 numbers/3.md
0 2024-11-16 14:26 numbers/7.md
296 2024-11-16 14:22 secret-thoughts.md
0 2024-11-16 14:26 gods/gossip.md
--------- -------
296 14 files
Find most recently modified files
~/workspace/play
❯ find . -printf "%T@ | %Tc | %p\n" | sort -rn | head -n 8
1731786108.4763963550 | Sat 16 Nov 2024 02:41:48 PM EST | ./archive.zip
1731786108.4763963550 | Sat 16 Nov 2024 02:41:48 PM EST | .
1731786063.2726562920 | Sat 16 Nov 2024 02:41:03 PM EST | ./numbers
1731785799.0167644310 | Sat 16 Nov 2024 02:36:39 PM EST | ./books/parts i didnt like.md
1731785799.0167644310 | Sat 16 Nov 2024 02:36:39 PM EST | ./books
1731785213.3907332660 | Sat 16 Nov 2024 02:26:53 PM EST | ./gods/gossip.md
1731785213.3907332660 | Sat 16 Nov 2024 02:26:53 PM EST | ./gods
1731785203.2306722210 | Sat 16 Nov 2024 02:26:43 PM EST | ./books/highlights.md
Here’s a first attempt. The first column is important because it’s how sort is able to do its work but I don’t actually want to see it. This fixes that up with the cut
command:
~/workspace/play
❯ find . -printf "%T@ | %Tc | %p\n" | sort -rn | cut -d"|" -f2,3 | head -n 8
Sat 16 Nov 2024 02:41:48 PM EST | ./archive.zip
Sat 16 Nov 2024 02:41:48 PM EST | .
Sat 16 Nov 2024 02:41:03 PM EST | ./numbers
Sat 16 Nov 2024 02:36:39 PM EST | ./books/parts i didnt like.md
Sat 16 Nov 2024 02:36:39 PM EST | ./books
Sat 16 Nov 2024 02:26:53 PM EST | ./gods/gossip.md
Sat 16 Nov 2024 02:26:53 PM EST | ./gods
Sat 16 Nov 2024 02:26:43 PM EST | ./books/highlights.md
And I’m even happier with this:
~/workspace/play
❯ find . -type f -printf "%T@ | %TY-%Tm-%Td %TH:%TM %p\n" | sort -n -r | cut -d "|" -f 2 | head -n 8
2024-11-16 14:41 ./archive.zip
2024-11-16 14:36 ./books/parts i didnt like.md
2024-11-16 14:26 ./gods/gossip.md
2024-11-16 14:26 ./books/highlights.md
2024-11-16 14:26 ./numbers/10.md
2024-11-16 14:26 ./numbers/9.md
2024-11-16 14:26 ./numbers/8.md
2024-11-16 14:26 ./numbers/7.md
Nicer manpage reading
We can have much nicer manpages by setting a variable for the manpager. This goes in my ~/.zshrc
export MANPAGER="nvim +Man\!"
End of day
Today was a quiet day of working from my apartment before having a big adventure exploring NYC and seeing the a fancy event at the library and exploring grand central station.
Worked on Today
- Added some analytics to my notes/presentation using plausibleas a privacy respecting user-counter
- Added a note to the start/end of the presentation so future readers can navigate through the presentation themselves: https://friend.slides.nicole.computer/1
- Deployed friend presentation to Cloudflare pages (I’m aiming to move everything there eventually): https://notes.nicole.computer/daily/2024-11-16#moving-presentation-to-cloudflare
- Spent a lot of time learning about / practicing with
xargs
: https://notes.nicole.computer/daily/2024-11-16#xargs - Started planning a (just for now) secret project
Tomorrow
- Maybe secret project stuff
- Working on a small silly website to show off pictures of my stuffed Lion exploring NY
- more xargs practice (until it feels comfortable and familiar)