Automated updates: 2021-09-22

This commit is contained in:
John Colagioia 2021-09-22 07:36:13 -04:00
parent d592190430
commit 231bbc1dbf
1 changed files with 116 additions and 0 deletions

116
2021-09-22-startup.md Normal file
View File

@ -0,0 +1,116 @@
---
layout: post
title: Startup, but Not Really Startup
date: 2021-09-22 07:36:23-0400
tags: [programming, techtips, linux]
summary: Running on or near startup on Linux, just using the shell
thumbnail: /blog/assets/work-technology-vintage-wheel-retro-clock-606288-pxhere.com.jpg
offset: -14%
---
This is a lightweight tip that's *definitely* just so that I have someplace to look it up, when I need to do it next.
Among the conveniences that I have created on my computer, my favorite is probably opening up the draft for the upcoming [**Entropy Arbitrage** newsletter](https://entropy-arbitrage.mailchimpsites.com/) when I log in. I keep the drafts in a non-obvious folder with many other projects that don't yet deserve their own repository, so rather than try to remember where the file is when I have something to add for the month, it's always open in the text editor that I use for most simple work.
![Gears](/blog/assets/work-technology-vintage-wheel-retro-clock-606288-pxhere.com.jpg "I'm bringing back the gears image, because I didn't feel like looking for metaphors for starting things...")
So, this is a walk-through of how that process fits together.
Note that I run [Ubuntu](https://ubuntu.com/) at this time. I am well aware that the "Linux community" often has things to say about Ubuntu and Canonical that are somewhat less than kind, but the same community gives a pass to other companies that have the same issues. I also don't particularly care; it works.
## Where to Begin...?
There are many systems that can be considered a Linux startup. Among others that I've probably forgotten, there are...
* System startup, generally used for services, and are generally handled by adding fiddly scripts that need precise names, so that they are started with the right "cohort." For Ubuntu, [`systemd`](https://en.wikipedia.org/wiki/Systemd) handles this, despite a lot of complaints---and unfortunate harassment---from individuals who resent the fact that Linux is no longer primarily for hobbyists using 1990s technology.
* Logging in requires starting a shell, when the system runs the `.profile` script. It's obviously a closer solution.
* When opening a shell---for a command prompt---*other* than login, there's a different file that runs, usually named after the shell. Since I run [BASH](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) in most cases, the magic file is `.bashrc`.
* Graphical desktop environments have a startup manager. In theory, this should be the "correct" solution, but has limitations on flexibility and isn't easily made portable.
The `systemd` option occurs before anybody can log in, so it's probably not going to work. Using `.bashrc` doesn't make much sense, since I don't *always* open a shell on startup. That leaves the other two choices.
## Proof of Concept
Because it's more flexible---I can run whatever code I please with whatever conditions I choose---I decided to work with `.profile` and see how that goes. I added the following to the end of that file.
```sh
nohup /usr/bin/gedit ~/path/to/newsletter/$(date +"%Y-%m").md &
```
If you're not familiar with what's happening, here...
* `nohup` is an old standard command that means "no hang up," meaning that the command shouldn't stop when the shell ends.
* `date` takes a formatter, in this case a four-digit year, a hyphen, and a two-digit month.
* The ampersand (`&`) says to run the program in the background.
Since [gEdit](https://en.wikipedia.org/wiki/Gedit) is the default text editor, that works. But it could work *better*.
## Maybe That's Not the Editor
For a few months, gEdit on Ubuntu had some trouble with resource management. It'd open a large file or many files, stall---which derailed whatever I was doing---and then ultimately crashed. While the relevant developers were fixing that, I moved to a different default editor.
If this ever happens again, I don't want to need to remember to update my `.profile` to reflect that change, so we should probably generalize the editor. Unfortunately, that's a multi-step process.
```sh
tempfile=$(mktemp --suffix=.txt)
echo "Time to wake up!" > "$tempfile"
editor=$(mimetype -b "$tempfile" | xargs xdg-mime query default | xargs whereis -b | cut -f2 -d' ')
nohup "$editor" ~/path/to/newsletter/$(date +"%Y-%m").md &
rm "$tempfile"
```
For the first two lines, we create a temporary text file with some pointless text, enough for any programs to recognize that it's just a test file. Then, inside the parentheses---which tells the shell to run the command and save the output to assign to a variable---we get the [MIME](https://en.wikipedia.org/wiki/MIME) type of that text file, which should be "text/plain." The `xargs` command takes every word in its input and calls a command on it, in this case querying the MIME database for the default handler---if we needed to do this normally, it would look like this.
```sh
xdg-mime query default "text/plain"
```
That gives us the name of the default application. We then use `xargs` again---we shouldn't need to, but *not* doing so threw an error---to ask for the location of "binary files" (non-text) installed with that application's name. Finally, we pick the first item in that list, after the heading. That gives us a path-and-executable to run, which we store in the `$editor` variable.
Finally, we *use* the `$editor` variable to open the file as above, and delete the temporary file.
That's much better, except for the...
## Dueling ~~Banjos~~ Editors
For some reason, [Visual Studio Code](https://code.visualstudio.com/) and [VSCodium](https://vscodium.com/) open login-shells when they start, which executes the code in `.profile`, and so brings my mailing list draft to the front whenever I go to edit *code*. That's survivable, but not ideal.
However, then---as has probably been mentioned in a [developer journal](/blog/tag/devjournal) post---I started using [RVM](https://rvm.io/) to deal with diverging Ruby versions. For some reason that I hope is beyond just being difficult, most critical RVM features only work in login-shells. So now, every shell I open is a login-shell, so that messes around with the editor a *lot* more than I'd like it to. It probably wouldn't take long to figure out why---one obvious guess comes to mind while I wrote this, in fact---but if something like this happened *twice*, it's going to happen again.
So, the next improvement is to say that we're effectively only going to do this once per log-in. Or maybe "approximately once" is better. A slip of the finger can accidentally *close* the editor on startup, so sometimes I'll want to call it back up. That produces something like this.
```sh
uptime=$(cut -f1 -d' ' /proc/uptime | cut -f1 -d'.')
if [ $uptime -lt 60 ]
then
tempfile=$(mktemp --suffix=.txt)
echo "Time to wake up!" > "$tempfile"
editor=$(mimetype -b "$tempfile" | xargs xdg-mime query default | xargs whereis -b | cut -f2 -d' ')
nohup "$editor" ~/path/to/newsletter/$(date +"%Y-%m").md &
rm "$tempfile"
fi
```
This gets the number of seconds that the system has been running and, if it's less than sixty (one minute), *then* open the editor. Skip it, if it's later. So now, if I accidentally close the editor when it opens, I can open a terminal window---which now starts a login-shell---and get it back.
### Do We Have the Time? Do We *Need* It?
An alternate possibility would have been to see if the editor is running, and only open it if not. However, to keep the editor implicit, this would either need to create a new temporary text file for every shell that opens, *or* need a permanent text file, and hope that nobody ever deletes it, removes it, or replaces the contents with something that `mimetype` recognizes as different.
Since neither of those possibilities appeals to me, I went with the current up-time, and will deal with re-opening the file at the rare times that I accidentally close the editor *after* the first minute.
## Other Possibilities
The above code is the final version for me, but there's probably some room for improvement.
For example, dealing with temporary files is always a mild security risk, since another process can snoop on them and modify the contents. I'm willing to risk it, here, since I'm the only person using my computer, the file contains no important information, and its entire lifespan is probably less than a microsecond in any case where I don't need to immediately reboot the computer.
In addition, since this is for the newsletter, it might make sense to open the current month's draft *and* the draft for the previous month, if we haven't reached the Saturday that it'll be released.
You get the idea. The reason I chose to use `.profile` was to get the flexibility in details and conditions, so this can now do anything, effectively. But for most purposes, I'd recommend just using the graphical tool and save the headaches.
#### <i class="fab fa-ubuntu"></i>
* * *
**Credits**: The header image is [work, technology, vintage, wheel, retro, clock](https://pxhere.com/en/photo/606288), by an uncredited PxHere photographer, is made available under the terms of the [CC0 1.0 Universal Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/).