Books of 2023

List of books I read in 2023. Also see the list of 2022. The date indicated denotes the date I started reading the book.

2023-01-04 - The Twisted Ones by T. Kingfisher - 385 pages by
2023-01-29 - A Psalm For The Wild-built by Becky Chambers - 147 pages
2023-01-31 - 1984 by George Orwell - 298 pages

Xanth

2023-01-10 - Isle Of View - Xanth #13 by Piers Anthony - 344 pages

Harry Potter

2023-01-15 - Harry Potter And The Sorcerer's Stone by J. K. Rowling - 309 pages
2023-02-04 - Harry Potter And The Chamber Of Secrets by J. K. Rowling - 341 pages

2023-xx-xx - Harry Potter And The Prisoner Of Azkaban by J. K. Rowling - 435 pages
2023-xx-xx - Harry Potter And The Goblet Of Fire by J. K. Rowling - 734 pages
2023-xx-xx - Harry Potter And The Order Of The Phoenix by J. K. Rowling - 870 pages
2023-xx-xx - Harry Potter And The Half-blood Prince by J. K. Rowling - 652 pages
2023-xx-xx - Harry Potter And The Deathly Hallows by J. K. Rowling - 759 pages

Dresden Files

2023-01-20 - Cold Days - Dresden Files #13 by Jim Butcher - 614 pages

2023-xx-xx - The House In The Cerulean Sea by T. J. Klune - 385 pages

Leave A Reply

PHP: Find the second (or third) occurrence of a substr in a string

I needed to find the second occurrence of a substring inside of a larger string. PHP has strpos() which gets you the first occurrence, but nothing beyond that. I wrote a wrapper function around strpos() to let you specify the number you want to find. Returns false if nothing is found.

function strpos_num(string $haystack, string $needle, int $num) {
    $offset = 0;
    $length = strlen($needle);
    $pos    = null;

    for ($i = 0; $i < $num; $i++) {
        $pos = strpos($haystack, $needle, $offset);

        // Short circuit continued lookups if we don't find anything
        if ($pos === false) { return false; }

        $offset = $pos + $length;
    }

    return $pos;
}
Leave A Reply

Perl: Human size in color

I use human_size() a lot in Perl, and sometimes it's nice to have a colored version. Here is a quick colorized version:

sub human_size_c {
    my $size = shift();
    if (!$size) { return undef; }

    if    ($size >= (1024**5) * 0.98) { $size = sprintf("\e[38;5;167m%.1fP\e[0m", $size / 1024**5); }
    elsif ($size >= (1024**4) * 0.98) { $size = sprintf("\e[38;5;105m%.1fT\e[0m", $size / 1024**4); }
    elsif ($size >= (1024**3) * 0.98) { $size = sprintf("\e[38;5;45m%.1fG\e[0m" , $size / 1024**3); }
    elsif ($size >= (1024**2) * 0.98) { $size = sprintf("\e[38;5;47m%.1fM\e[0m" , $size / 1024**2); }
    elsif ($size >= 1024)             { $size = sprintf("\e[38;5;226m%.1fK\e[0m", $size / 1024);    }
    elsif ($size >= 0)                { $size = sprintf("\e[38;5;160m%dB\e[0m"  , $size);           }

    return $size;
}

See also: Original human_size()

Leave A Reply

Perl: Remove an item from array

If you want to remove an item from an array you can use a inverse grep filter like this:

my @x = qw(foo bar baz orange);
@x    = grep { !/orange/ } @x;

or

my @x = qw(foo bar baz orange);
@x    = grep { $_ ne 'orange' } @x;
Leave A Reply

Perl: Read from multiple files with one filehandle

I have a directory of data files I wanted to read line-by-line simply. You can loop through each file, open a filehandle, process the lines, close the filehandle, but that can be repetitive. Perl has a unique mechanism where it will iterate across all the files in the @ARGV array automatically. You can fake out the @ARGV array with your own list of files and then iterate accordingly:

local @ARGV = sort(glob("/tmp/data/*.txt"));

# Special ARGV filehandle reads all the files sequentially
while (my $line = readline(ARGV)) {
    print $line;
}
Leave A Reply

Perl: Creating a reference to a subroutine

Perl allows you to create a reference to subrouting and store it in a variable. This allows subroutines to be passed around to other functions. In Perl speak these are called coderefs. There are two ways to create them:

my $one = sub { print "Hello world!"; }
my $two = \&hello_world;

sub hello_world {
    print "Hello world!";
}

Calling a code reference is simple:

$coderef->(); # No params
$coderef->($param1, $param2);
Leave A Reply

Perl: Sort an array of IP addresses

I have a list of IP addresses that I want sorted in a human readable fashion. A simple sort() on a list of IPs will not work because the octets may be: one, two, or three digits long which confuses sort(). Here is a simple sorting function for a list of IP addresses:

my @ips    = qw(198.15.0.20 4.2.2.1 10.11.1.1 10.100.1.1 65.182.224.40);
my @sorted = sort by_ip_address @ips;
sub by_ip_address {
    return ip2long($a) <=> ip2long($b);
}

Note: You will need my ip2long() function for this to work.

Leave A Reply

Linux: Check if a process is running

You can list all the running processes on a Linux box with ps aux, but often you're looking for a specific process. This is pretty easily accomplished with grep:

ps aux | grep /usr/sbin/sshd

The problem with this is that you often pick up you own grep in the output:

$ ps aux | grep /usr/sbin/sshd
root         883  0.0  0.0  76640  7428 ?        Ss   Oct18   0:00 /usr/sbin/sshd -D -oCiphers...
bakers     11691  0.0  0.0  12148  1104 pts/0    S+   08:09   0:00 grep --color=auto /usr/sbin/sshd

The quick and dirty solution is to do some trickery with a regular expression and grep:

$ ps aux | grep -P '/usr/sbin/[s]shd'
root         883  0.0  0.0  76640  7428 ?        Ss   Oct18   0:00 /usr/sbin/sshd -D -oCiphers...

The square brackets tell grep to match a character class with only one character in it. This prevents grep from picking up itself, but still matches what you want.

Leave A Reply

Making ffmpeg truly quiet (non verbose)

ffmpeg is a great program, but can be rather verbose in it's output. This can be problematic if you're trying to use ffmpeg in a script. The best way to make ffmpeg truly silent in it's output is with the following options:

ffmpeg -hide_banner -loglevel error ...

This will hide the startup banner, and any encoding stats. Assuming your encode goes normally you shouldn't get any output at all.

Leave A Reply

Perl: Create a temporary file that's automatically removed on script termination

I need a random temporary file to put some data in while my script executes. The file should be removed automatically after the script completes. Enter File::Temp which handles all of this for you.

use File::Temp;

my ($fh, $filename) = File::Temp::tempfile(UNLINK => 1);

Alternately if you need a temporary directory that's automatically removed on completion you can use:

use File::Temp;

my $dir = File::Temp::tempdir(CLEANUP => 1);

Note: File::Temp is a core module, so you already have it.

Leave A Reply

CentOS Stream and Rocky Linux End of Life

CentOS and Rocky end of life:

Distro Active Support Security
Centos 7 Aug 6, 2020 Jun 30, 2024
Centos 8 Stream May 31, 2024 N/A
Centos 9 Stream May 31, 2027 N/A
Rocky Linux 8 May 31, 2024 May 31, 2029
Rocky Linux 9 May 31, 2025 May 31, 2032
Leave A Reply

Using Vim as a time machine

If you're editing a file in Vim you can rewind time to a previous version of the file with the earlier command. You can go backwards (or forwards) in the history of a file based on a given time measurement. This can be helpful if you mess up your file and just want to rollback to a previous version.

:earlier 5m

or

:later 5m

Reddit had some interesting discussion on what you can do with this feature.

Note: Alternately you can use :e! to reload the file from disk if you haven't saved since your mess up.

Leave A Reply

Linux: Using the parallel command to use all your cores

Linux has a cool utility named parallel that let's you run many tasks simultaneously. It's useful for older tasks that aren't multi-threaded. I often use it to encode MP3s in parallel because lame only uses one core. On a modern machine with 8+ cores, it's much more efficient to use them all at the same time. You need to feed parallel a list of files and then use the {} pragma to replace the string with the incoming filename. Parallel has similar syntax to xargs.

find src/dir -type f -iname *.mkv | parallel vid2mp3 '{}' --track 1 --out /var/tmp/

This sample command will invoke parallel command, detecting how many cores are available, and spawn that many threads of the output command. All references to {} will be replaced with the incoming filename.

Leave A Reply

Perl: Count days until payday in a one-liner

Pay day is once a month on the 7th. Can you calculate the number of days until payday using a Perl one-liner in less than a hundred characters? I wasn't able to do it, but some creative Redditors were:

perl -E '$_=-1;for($t=time;$d!=7;$t+=86400){$_++;$d=(localtime($t))[3]}say'
Leave A Reply

Mixing privacy channels and CTCSS/DCS for GMRS radios

Two way radios can utilize privacy channels to limit the amount of chatter on a given channel. Many consumer grade radios use the term "privacy channels" to mean CTCSS or DCS coding. My Baofeng radios allow setting CTCSS/DCS directly so it's important to have a mapping between generic "privacy channels" and the raw codes.

Radios using the "common" settings of 1 through 121 include: Motorola, Uniden, and Backcountry Access.

Common CTCSS Freq
1 67.0
2 71.9
3 74.4
4 77.0
5 79.7
6 82.5
7 85.4
8 88.5
9 91.5
10 94.8
11 97.4
12 100.0
13 103.5
14 107.2
15 110.9
16 114.8
17 118.8
18 123.0
19 127.3
20 131.8
21 136.5
22 141.3
23 146.2
24 151.4
25 156.7
26 162.2
27 167.9
28 173.8
29 179.9
30 186.2
31 192.8
32 203.5
33 210.7
34 218.1
35 225.7
36 233.6
37 241.8
38 250.3
Common DCS Code Baofeng
39 023 D023N
40 025 D025N
41 026 D026N
42 031 D031N
43 032 D032N
44 043 D043N
45 047 D047N
46 051 D051N
47 054 D054N
48 065 D065N
49 071 D071N
50 072 D072N
51 073 D073N
52 074 D074N
53 114 D114N
54 115 D115N
55 116 D116N
56 125 D125N
57 131 D131N
58 132 D132N
59 134 D134N
60 143 D143N
61 152 D152N
62 155 D155N
63 156 D156N
64 162 D162N
65 165 D165N
66 172 D172N
67 174 D174N
68 205 D205N
69 223 D223N
70 226 D226N
71 243 D243N
72 244 D244N
73 245 D245N
74 251 D251N
75 261 D261N
76 263 D263N
77 265 D265N
78 271 D271N
79 306 D306N
80 311 D311N
81 315 D315N
82 331 D331N
83 343 D343N
84 346 D346N
85 351 D351N
86 364 D364N
87 365 D365N
88 371 D371N
89 411 D411N
90 412 D412N
91 413 D412N
92 423 D423N
93 431 D431N
94 432 D432N
95 445 D445N
96 464 D464N
97 465 D465N
98 466 D466N
99 503 D503N
100 506 D506N
101 516 D516N
102 532 D532N
103 546 D546N
104 565 D565N
105 606 D606N
106 612 D612N
107 624 D624N
108 627 D627N
109 631 D631N
110 632 D632N
111 654 D654N
112 662 D662N
113 664 D664N
114 703 D703N
115 712 D712N
116 723 D723N
117 731 D731N
118 732 D732N
119 734 D734N
120 743 D743N
121 754 D754N

Table borrowed and simplified from k0tfu.org

Leave A Reply