This commit is contained in:
2026-04-27 01:30:33 +02:00
parent 9e29b8b096
commit 49e7930541
80 changed files with 924 additions and 703 deletions

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
*.pdf
*.gif
*.jpeg

116
Makefile
View File

@@ -1,13 +1,16 @@
MAKEFLAGS += -j MAKEFLAGS += -j
MAKEFLAGS += -s MAKEFLAGS += -s
EDITOR ?= vi EDITOR ?= vi
FZF != command -v sk || command -v fzy || command -v fzf || \ PAGER ?= less -Ri
{ echo install a fuzzy finder && exit 1 ;} READER != command -v mdless bat glow less more pg | head -1
FZF != command -v fzf sk | head -1
ifeq "$(FZF)" ""
$(info Install fzf)
endif
ifeq "$(FZF)" "/usr/bin/fzy" ifeq "$(FZF)" "/usr/bin/fzy"
FZF += -i FZF += -i
else
FZF += --print-query | tail -1
endif endif
spill_contents = sed -e '1,/---/d' spill_contents = sed -e '1,/---/d'
@@ -19,18 +22,9 @@ help: ## Print the help message
articles != find * -type f -name "*.md" articles != find * -type f -name "*.md"
dirs != ls -d */ default += .dbs/notes.rec
categories = $(patsubst %/, %, $(dirs))
databases = $(patsubst %, .dbs/%.rec, $(categories))
default += $(databases)
default += db.rec
default += .dbs/map.fmt default += .dbs/map.fmt
$(foreach dir, $(categories), \
$(eval .dbs/$(dir).rec: $(wildcard $(dir)/*)) \
)
%/: %/:
mkdir $@ mkdir $@
@@ -38,34 +32,48 @@ $(foreach dir, $(categories), \
include cmd.mk include cmd.mk
$(databases): .dbs/%.rec: %/ | .dbs/ .dbs/head.rec: | .dbs/ $(lists)
$(info making $(@F))
for entry in $(shell find $< -type f -name "*.md") ; do \
printf "path: %s\n" "$$entry" ;\
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
while read -r line; do if [ -z "$${line#*:}" ] ; then type="$$line"; else echo "$$line" | sed -r "s/- (.*)/$$type \1/" | sed s'/tags: /tag: /' ; fi ; done ;\
printf "wordcount: %s\n\n" "$$(wc -w < $$entry)" ;\
done > $@
# This two-variable read can only happen because of the quotes in the titles.
db.rec: $(databases)
$(info rebuilding from $? )
printf '%s\n' '%rec: guide' > $@ printf '%s\n' '%rec: guide' > $@
printf '%s\n' '%key: title' >> $@ printf '%s\n' '%key: path' >> $@
printf '%s\n' '%type: requires rec guide' >> $@ printf '%s\n' '%type: requires rec guide' >> $@
printf '%s\n' '%type: provides rec guide' >> $@ printf '%s\n' '%type: provides rec guide' >> $@
printf '%s\n' '%type: wordcount int' >> $@ printf '%s\n' '%type: wordcount int' >> $@
printf '%s\n\n' '%sort: wordcount' >> $@ printf '%s\n\n' '%sort: wordcount' >> $@
cat $^ >> $@
recsel $@ -e "requires != ''" -CR title,requires |\ .dbs/new.rec: $(wildcard */*.md */*/*.md) | .dbs/head.rec
while read title requires; do \ $(info Updating: $?)
for provider in "$$requires" ; do \ grep -q guide $@ 2>/dev/null || cp $| $@
recset --verbose $@ -e "title = '$${provider}'" -f provides -a "$${title}" ;\ @-$(foreach entry, $?, \
done ;\ recdel -t guide $@ -e "path = '$(entry)'" 2>/dev/null ;\
done )
sed -i 's/"//g' $@ for entry in $? ; do \
recfix --sort $@ echo '' ;\
$(info Created main database: $@) printf "path: %s\n" "$$entry" ;\
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
while read -r line; do if [ -z "$${line#*:}" ] ; then type="$$line"; else echo "$$line" | sed -r "s/- (.*)/$$type \1/" | sed s'/tags: /tag: /' ; fi ; done ;\
printf "wordcount: %s\n" "$$(wc -w < $$entry)" ;\
echo 'cmd: ' ;\
sed '1,/^---$$/d' $$entry | sed 's/^.*/+ &/' ;\
echo '' ;\
done >> $@
.dbs/requires.rec: .dbs/new.rec
recinf -d $< > $@
echo "" >> $@
recsel $< -t guide -j requires -G requires -p 'path,title,tag,wordcount,requires_path:requires,requires_requires:requires,cmd' >> $@
.dbs/notes.rec: .dbs/requires.rec .dbs/new.rec
recinf -d $< > $@
echo '' >> $@
sed '/^%/d' $^ | recsel -G path | recsel -U >> $@
default += db.rec
db.rec: command.rec .dbs/notes.rec
recinf -d $< > $@
echo '' >> $@
sed '/^%/d' $^ | recsel -U -p 'title:aim,aim,cmd,note,shell,tag,bin:tag' >> $@
$(info Making main database: $@)
.git/info/exclude: $(default) .git/info/exclude: $(default)
@echo $^ | tr ' ' '\n' > $@ @echo $^ | tr ' ' '\n' > $@
@@ -76,38 +84,40 @@ default += .git/info/exclude
database: $(default) ## Make a recfiles database database: $(default) ## Make a recfiles database
.dbs/map.fmt:| .dbs/ .dbs/map.fmt:| .dbs/
printf '%s\n' '[ {{requires[0]}} ] --> [ {{title}} ] {border-style: dashed;}' > $@ printf '%s\n' '[ {{requires[0]}} ] --> [ {{path}} ] {border-style: dashed;}' > $@
printf '%s\n' '[ {{requires[1]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ printf '%s\n' '[ {{requires[1]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[2]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ printf '%s\n' '[ {{requires[2]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[3]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ printf '%s\n' '[ {{requires[3]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[4]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ printf '%s\n' '[ {{requires[4]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
.PHONY: map .PHONY: map
map: db.rec .dbs/map.fmt ## Show knowledge dependency map map: .dbs/requires.rec .dbs/map.fmt ## Show knowledge dependency map
recsel -t guide $< -e 'requires != ""' -p title,requires | recfmt -f .dbs/map.fmt |\ recsel -t guide $< -e 'requires != ""' -p path,requires | recfmt -f .dbs/map.fmt |\
grep -vF '[ ]' | graph-easy --boxart | $${PAGER} grep -vF '[ ]' | graph-easy --boxart 2>/dev/null | ${PAGER} -S
.PHONY: clean .PHONY: clean
clean: ## Remove all generated files clean: ## Remove all generated files
$(RM) $(default) $(RM) -r $(default) .dbs/
.PHONY: article .PHONY: article
article: **/ **/**/ ## Write a new article article: */ */*/ ## Write a new article
category=$(shell echo $^ | tr ' ' '\n' | $(FZF) ) \ category=$(shell echo $^ | tr ' ' '\n' | $(FZF) --print-query | tail -1 ) \
&& read -p "Article title? " name \ && read -p "Article title? " name \
&& filename="$$(echo "$$name" \ && filename="$$(echo "$$name" \
| cut -d: -f1 \ | cut -d: -f1 \
| tr -cd '[:alpha:]' | tr '[A-Z ]' '[a-z_]' )" \ | tr '[A-Z ]' '[a-z_]' | tr -cd '[:alpha:]_' )" \
&& $(MAKE) -e TITLE="$$name" "$$category"/"$$filename.md" && $(MAKE) -e TITLE="$$name" "$$category"/"$$filename.md"
.PHONY: all
all: $(default) ## All file targets
%.md: %.md:
[ -d "$(@D)" ] || mkdir $(@D) [ -d "$(@D)" ] || mkdir $(@D)
printf '%s\n' '---' >> $@ printf '%s\n' '---' >> $@
printf 'title: %s\n' '$(TITLE)' >> $@ printf 'title: %s\n' '$(TITLE)' >> $@
echo "tags: " >> $@ printf "tags: " >> $@
echo $(@D) | sed 's#\/#\n- #g' >> $@ echo $(@D) | sed 's#\b\w#\n- &#g; s/\///g' >> $@
printf '%s\n\n' '---' >> $@ printf '%s\n\n' '---' >> $@
$(EDITOR) +5 $@ $(EDITOR) +5 $@
git add $@
git commit -m"article: $(TITLE)"

140
README.md
View File

@@ -1,61 +1,103 @@
--- # Linux Knowledge Base
title: Linux Knowledge Base
---
The Linux Knowledge-Base provides quick-start guides for working with terminal programs. These notes Linux programs have grown into a searchable knowledge base.
If you like this style of short articles with a miniature database, then join me in my quest to remove the nausea of poorly-written documentation. # Usage
# Setup ## Setup
Install `make`, `recutils`, and any fuzzy-finder (i.e. `sk`, `fzy`, or `fzf`). Install `make`, `recutils`, and any a fuzzy-finder (like `fzf` or `sk`).
## Usage To find the options, run `make`.
## Queries
The fuzzy finder opens an interactive menu to find information.
There are two types of notes:
1. Short commands, catalogued by aim (in `command.rec`).
1. Short notes, mostly on getting set up with something (in the markdown files).
### Short Commands
Running `make check` will start a search of the snippets, ordered by what you
want to do, not by the name of the binary:
```
Hard reset ntp service
-> Quickly find and open run-command files
Turn markdown into a man page
Rotate a video
Translate a media file to a new type
```
The output is a couple of lines of code, with changeable components as variables:
```
alias rrc='$PAGER "$(find . -maxdepth 2 -name "*rc" | fzf)"'
```
### Guides
The notes are mostly written like a heavily commented script.
Most are setup guides.
### The Function
Running `make function` outputs a shell function which searches through this
knowledge base, so you don't have to `cd` to use it.
Set up the database and try a few queries:
```sh ```sh
make lk(){
make database /usr/bin/mdless "$(recsel ${your-path-here}/lk/db.rec \
-q "$(recsel ${your-path-here}/lk/db.rec -CP title,tag \
| sort -u \
| /usr/bin/fzf )" -CP path \
| fzf --sync -1 --preview='less -iR {}' )"
}
```
recsel db.rec -m 3 Add the function to your bash shell like this:
recsel db.rec -q database
recsel db.rec -e "title = 'ssh'"
recsel db.rec -e "title ~ 'ssh'"
recsel db.rec -e "title ~ 'bash'" -R title,wordcount
recsel db.rec -t guide -j provides -G title \ ```bash
-e "title = 'ssh'" \ make function
-p 'sum(provides_wordcount)' make function >> ~/.bashrc
exec bash
lk
``` ```
# Style # Style
## No History, No Context
- Nobody cares about how the project started.
- Nobody wants to read what `ffmpeg` is, because anyone who wants to use it already knows what it is.
## State Knowledge Dependencies ## State Knowledge Dependencies
Articles should state what you need to understand in order to read them *at the start*. Articles should never link to other resources part-way through.
They should not assume the reader knows much beyond common terminal commands, and should not provide a link to some other resource half-way through an article. If the article assumes an understanding of GPG keys, then it should say that at the top.
People should be able to read documentation from the beginning, then keep going until the end, and then stop.
Setup guides should not send the reader on a detour through labyrinths of links.
People should be able to read an article from the beginning, then keep going until the end, and then stop. ## No History, No Context
Articles should not take a detour through a chain of other articles of unknown size.
[Do not Jaquays documentation](https://splint.rs/posts/no_links) Anyone who wants to read how to use OTP with GPG already knows what those words mean, so guides should not spend time explaining.
Anyone who doesn't know what GPG keys are can find the link to using them, which explains them better than using door-blocking devices as a metaphor for prime number factorization.
## Index by Purpose
Nobody wants to read about `grep`, they want to find words, like 'cat'.
They want to 'download a website', not learn about `wget`.
Guides should be created and indexed by purpose, not by binary.
## Be Opinionated ## Be Opinionated
- Guides should not ask the reader to select options half-way through. - Guides should not ask the reader to pick from a list of options.
- Options for different filesystems, databases, et c., should be written as separate guides. - Options for different filesystems, databases, et c., should be written as separate guides.
## Repetition Beats Reference ## Repetition Beats Reference
If a database requires three commands to set up, it's better to repeat those three commands for every program that requires a database than to just link to another file which discusses databases. If a database requires three commands to set up, it's better to repeat those three commands for every program that requires a database than to just link to another file which discusses databases.
## Show Arguments as Variables ## Show Options as Variables
Look at this line: Look at this line:
@@ -82,28 +124,51 @@ The answer is not obvious.
It's better to make all arbitrary values variables. It's better to make all arbitrary values variables.
```sh ```sh
git branch $branch_name name=new
git checkout $branch_name git branch ${name}
git checkout ${name}
PAGER='less -R' PAGER='less -R'
grep ls --color=always $HISTFILE | $PAGER grep ls --color=always $HISTFILE | $PAGER
``` ```
Now we can see what can be changed. Now we can see what can be changed.
## Assume People Follow the Instructions ### Show, Don't Tell
Articles should say what to type, not the output. Articles should say what to type, not the output.
If the command is `ls`, users will see files once they try the command, but the article does not need to provide an example list of files unless an important point has to be made about output. If the command is `ls`, users will see files once they try the command, but the article does not need to provide an example list of files unless an important point has to be made about output.
Once a user enters a new group, the change doesn't take effect until you log
in. This could be explained at length, or the reader can see what this means
for themselves:
```sh
groups
grep audio /etc/group
sudo usermod -aG audio $USER
groups
grep audio /etc/group
su $USER
groups
grep audio /etc/group
```
Troubleshooting steps can often be implied by adding commands which do nothing but check the results of previous commands.
# What's Wrong with Everything Else? # What's Wrong with Everything Else?
Why bother writing yet another cheat-sheet collection?
## Man pages ## Man pages
- Orders items by the alphabet rather than by relevance. - Orders items by the alphabet rather than by relevance.
- Often presumes you know everything except that one program. - Often presumes you know everything except that one program.
- Often written in the 80's, and it shows. - Often written in the 80's, and it shows.
- Zero respect for your time. - Zero respect for your time.
- Often references `info` pages (yuck). - Sometimes reference `info` pages (yuck).
## `curl cheat.sh` ## `curl cheat.sh`
@@ -114,9 +179,6 @@ If the command is `ls`, users will see files once they try the command, but the
# Current State # Current State
This started as a few personal notes, and will probably continue to look like that for some time.
It's a bit of a mess. It's a bit of a mess.
If you like the format, send me a pull request.
Systemd is taken as a default.
Non-systemd commands are mentioned when required for a distro, e.g. runit for Void Linux.

View File

@@ -4,7 +4,7 @@ tags:
- chat - chat
- omemo - omemo
requires: requires:
- profanity - chat/profanity.md
--- ---
Automate profanity with `--cmd`. Automate profanity with `--cmd`.

View File

@@ -28,3 +28,9 @@ Paste in the file then load the result to the right-hand clipboard:
wgetpaste -s dpaste -X wgetpaste -s dpaste -X
``` ```
---
title:
tags:
chat
---

25
cmd.mk
View File

@@ -1,18 +1,18 @@
cmds != recsel command.rec -t command -G bin -U -CP bin cmds != recsel command.rec -t command -G bin -CP bin | sort -u
lists = $(patsubst %,lists/%.md, $(cmds)) lists = $(patsubst %,lists/%.md, $(cmds))
default += $(lists) default += $(lists)
get_title = printf 'title: "%s"\n' '${1}' get_title = printf 'title: %s\n' '${1}'
get_tags = recsel -t $(basename $<) $< -G bin \ get_tags = recsel -t $(basename $<) $< -G bin \
-e 'bin = "$(1)"' -U -CP tag | \ -e 'bin = "$(1)"' -U -CP tag,bin | \
sed 's/.*/- &/' sed 's/.*/- &/'
list_commands = recsel -t $(basename $<) $< -e 'bin = "$(1)"' | \ list_commands = recsel -t $(basename $<) $< -e 'bin = "$(1)"' | \
recfmt -f lists.fmt recfmt -f lists.fmt
lists/%.md: command.rec | lists/ $(lists): lists/%.md: command.rec | lists/
@printf '%s\n' '---' > $@ @printf '%s\n' '---' > $@
@$(call get_title,$(basename $(notdir $@))) >> $@ @$(call get_title,$(basename $(notdir $@))) >> $@
@printf '%s\n' 'tags: ' >> $@ @printf '%s\n' 'tags: ' >> $@
@@ -22,3 +22,20 @@ lists/%.md: command.rec | lists/
.PHONY: cmd .PHONY: cmd
cmd: $(lists) ## Big lists of commands cmd: $(lists) ## Big lists of commands
.PHONY: function
function: ## Output a search function for .bashrc
${MAKE} --silent --touch query
printf '%s\n' 'lk(){'
${MAKE} --silent --dry-run query | sed 's/^/\t/'
printf '%s\n' '}'
.PHONY: query
query: db.rec ## Search the setup notes
passes=0 count=0; until [ "$$count" -eq "1" ] || [ "$$passes" -gt 2 ] ; do \
query="$$(recsel "${PWD}"/db.rec -p aim,tag | recsel -iq "$$query" -CP aim,tag | sort -u | fzf --preview='recsel "${PWD}"/db.rec -e "aim~{}"')" \
&& count="$$(recsel "${PWD}"/db.rec -q "$$query" -c )" ;\
passes=$$(( passes + 1 )) ;\
done \
&& recsel "${PWD}"/db.rec -q "$$query" | recfmt -f "${PWD}/lists.fmt" | ${PAGER}

View File

@@ -1,14 +1,11 @@
%rec: command %rec: command
%doc: shell command examples %doc: shell command examples
%type: aim line %type: aim line
%allowed: aim %allowed: aim cmd bin tag note shell
+ cmd bin
+ tag
+ shell
%unique: shell %unique: shell
aim: Put output into column aim: Put output into columns
cmd: du -h /etc/* | column cmd: ip a | grep inet | column -ts' '
shell: sh shell: sh
bin: column bin: column
tag: format tag: format
@@ -19,14 +16,16 @@ shell: sh
bin: column bin: column
tag: format tag: format
aim: Give columns names (`-N`), so you can hide some (`-H`) aim: Sort lines into columns with names
cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID /etc/passwd cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID /etc/passwd
note: Hide some columns with `-H`.
shell: sh shell: sh
bin: column bin: column
tag: format tag: format
aim: Reorder with `-O` (unspecified items remain) aim: Sort lines into columns and reorder them
cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID -O User,Description,shell /etc/passwd cmd: column -ts: -N User,PW,UID,GID,Description,Home,shell -H PW,GID -O User,Description,shell /etc/passwd
note: Unspecified items remain.
shell: sh shell: sh
bin: column bin: column
tag: format tag: format
@@ -38,48 +37,55 @@ bin: column
tag: format tag: format
tag: json tag: json
aim: Make a QR Code image: aim: Make a QR Code image
cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "$FILE".png cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "${file}".png
shell: sh shell: sh
bin: qrencode bin: qrencode
tag: qr tag: qr
aim: Make a QR Coded message in the terminal: aim: Make a QR Coded message in the terminal
cmd: qrencode -t ansi "Hello World" cmd: qrencode -t ansi "Hello World"
shell: sh shell: sh
bin: qrencode bin: qrencode
tag: qr tag: qr
aim: Read a QR Code image: aim: Read a QR Code image
cmd: zbarimg $FILE cmd: zbarimg ${file}
shell: sh shell: sh
bin: qrencode bin: qrencode
tag: qr tag: qr
aim: Show wifi QR code (only with Network Manager): aim: Show wifi QR code (only with Network Manager)
cmd: nmcli device wifi show-password cmd: nmcli device wifi show-password
shell: sh shell: sh
bin: qrencode bin: qrencode
bin: nmcli
tag: qr tag: qr
tag: wifi tag: wifi
aim: Combine many recfiles of different types into one: aim: Combine many recfiles of different types into one
cmd: sed '1i\ ' *.rec > all.rec cmd: sed '1i\ ' *.rec > all.rec
shell: sh shell: sh
bin: sed bin: sed
tag: recfiles tag: recfiles
tag: database tag: database
aim: Combine many recfiles of the same type into one: aim: Combine many recfiles of the same type into one
cmd: recinf -d -t ${type} ${one}.rec > ${all}.rec cmd: recinf -d -t ${type} ${one}.rec > ${all}.rec
+ sed '/^%/d' ${one}.rec ${two}.rec > all.rec + sed '/^%/d' ${one}.rec ${two}.rec > all.rec
note: The strange syntax used by `sed` only makes sense after using [ed](writing/ed.md)
shell: sh shell: sh
bin: sed bin: sed
bin: recinf bin: recinf
tag: recfiles tag: recfiles
tag: database tag: database
aim: Remotely edit a file with vim: aim: Roll a die
cmd: echo $(( RANDOM % 6+1 ))
shell: bash
tag: random
aim: Remotely edit a file with vim
cmd: vim scp://${server}/~/${file} cmd: vim scp://${server}/~/${file}
cmd: vim scp://${user}@${server}:${port}//${path}/${file} cmd: vim scp://${user}@${server}:${port}//${path}/${file}
shell: sh shell: sh
@@ -87,19 +93,363 @@ bin: vim
bin: scp bin: scp
tag: network tag: network
aim: Find and replace across all files open in vim
cmd: :bufdo! %s/${pattern}/${replacement}/g
shell: sh
bin: vim
tag: writing
tag: replace
aim: Find and replace words, but confirm each replacement
cmd: vim -c "%s/${pattern}/${replacement}/gc" -c 'wq' ${file}
shell: sh
bin: vim
tag: replace
tag: substitution
tag: TUI
tag: writing
aim: Hard reset ntp service aim: Hard reset ntp service
cmd: sudo ntpd -q -g -x -n cmd: sudo ntpd -q -g -x -n
bin: ntpd bin: ntpd
tag: time tag: time
tag: system
aim: Check a service
cmd: sudo systemctl status mpd
shell: sh
bin: systemd
tag: system
tag: service
aim: Recognize service changes
cmd: sudo systemctl daemon-reload
shell: sh
bin: systemd
tag: system
tag: service
aim: Start a service (it stops when the computer shuts down)
cmd: sudo systemctl taskd.service start
+ sudo systemctl daemon-reload
shell: sh
bin: systemd
tag: system
tag: service
aim: Find out why the computer takes so long to start
cmd: sudo systemd-analyze
+ sudo systemd-analyze blame
shell: sh
bin: systemd
tag: system
tag: boot
aim: See what the computer is doing
cmd: journalctl -f
shell: sh
bin: journalctl
tag: system
aim: Check your own user services:
cmd: journalctl -f
shell: sh
bin: journalctl
tag: system
aim: Follow the `ssh` daemon service
cmd: journalctl -f -u sshd
shell: sh
bin: journalctl
tag: system
aim: Find errors since a date
cmd: date=2027-01-01
+ journalctl --since=${date} --grep="EXT4-fs error"
shell: sh
bin: journalctl
tag: system
aim: Limit the journal's size to 2 gigabytes
cmd: journalctl --vacuum-size=2G
shell: sh
bin: journalctl
tag: system
aim: Log the fact that you've installed your own `dnsmasq` on your system to `journalctl`, so that you can determine why your system's broken later
cmd: logger "Installed new dnsmasq"
+ sudo journalctl -f
shell: sh
bin: journalctl
tag: system
aim: Convert markdown table to csv aim: Convert markdown table to csv
cmd: mlr --imarkdown --ocsv cat ''.md cmd: mlr --imarkdown --ocsv cat ${file}.md
bin: mlr bin: mlr
tag: csv tag: csv
tag: markdown tag: markdown
tag: data tag: data
aim: Convert a csv file to markdown aim: Convert a csv file to markdown
cmd: mlr --icsv --omd cat ''.csv cmd: mlr --icsv --omd cat ${file}.csv
bin: mlr bin: mlr
tag: data tag: csv
tag: markdown
aim: Quickly find and open run-command files
cmd: alias rrc='$PAGER "$(find . -maxdepth 2 -name "*rc" | fzf)"'
bin: fzf
bin: find
tag: comfy
aim: Quickly hunt and kill processes
cmd: kill $(pgrep less | fzf -m --preview='ps {}')
note: Select many with shift/tab.
bin: fzf
tag: comfy
aim: Search for a short word
cmd: grep "\b${word}\b" ${file}
bin: grep
tag: search
aim: Extract words in quotes
cmd: grep -o "\b${word}\b" ${file}
bin: grep
tag: search
aim: Reformat variable for shell input
cmd: printf "%q\n" "${variable}"
bin: printf
tag: xargs
tag: stdout
aim: Find your public IP address
cmd: dig +short myip.opendns.com @resolver$((RANDOM % 4 + 1)).opendns.com
shell: bash
bin: dig
tag: ip
tag: network
aim: Turn markdown into a man page
cmd: man <(lowdown -stman ${file}.md)
cmd: top_title="Bugs in netcat"
+ someplace=LK
+ vol=Security
+ sec=6
+ lowdown -m manheader="${top_title}" -m source="${someplace}" -m volume="${vol}" -m section=${sec} -stman ${file}.md > ${file}.${sec}
+ man ./${file}.${sec}
shell: bash
bin: lowdown
bin: groff
bin: man
tag: markdown
aim: Convert jpg to png
cmd: magick ${input}.jpg ${output}.png
bin: magick
tag: vision
aim: Reduce jpg size by reducing quality
cmd: quality=70
+ magick ${input}.jpg -quality ${quality} ${output}.jpg
cmd: size=50
+ magick -resize ${size}% ${input}.jpg ${output}.jpg
bin: magick
tag: vision
aim: Reduce png size
cmd: magick ${input}.png png8:${output}.png
bin: magick
tag: vision
aim: Invert jpg colours
cmd: magick ${input}.jpg ${output}.jpg -negate
bin: magick
tag: vision
aim: Make jpg smaller
cmd: magick ${input}.jpg -resize 25% ${output}.jpg
bin: magick
tag: vision
aim: Trim images to border
cmd: magick -trim ${image}.png ${output}.png
bin: magick
tag: vision
aim: Make the white of an image transparent
cmd: magick -transparent white -fuzz 10% ${input}.png ${output}.png
bin: magick
tag: vision
note: The 'fuzz' option tells the computer that 'close to white' is fine. You might want to use 20% or higher fuzz.
aim: Give transparrent image a dropshadow
cmd: magick ${input}.png \( +clone -background black -shadow 50x8+0+5 \) +swap -background none -layers merge +repage ${output}.png
bin: magick
tag: vision
aim: Convert every jpg in directory to png
cmd: mogrify -format png *.jpg
bin: magick
tag: vision
aim: Convert from jpg to svg
cmd: magick -flatten ${input}.jpg ${output}.ppm
+ potrace -s ${output}.ppm -o ${svgout}.svg
bin: magick
tag: vision
aim: Make an image showing day of the week
cmd: magick -list font
+ font="$(magick -list font | grep -oP 'Font: \K.*' | head -1)"
+
+ magick -fill blue -font "${font}" -gravity center -pointsize 79 label:$(date +%A) day.png
bin: magick
tag: vision
aim: Make a meme
cmd: magick ${input} -font impact -fill white -pointsize 84 -stroke black -strokewidth 3 -gravity north -annotate +0+20 'TOP MEME TEXT' -gravity south -annotate +0+20 'BOTTOM MEME TEXT' ${output}
bin: magick
tag: vision
tag: memes
aim: Rotate a video
cmd: ffmpeg -i "${input}" -vf "transpose=1" "${out.mov}"
note:
+ | No. | Degrees | Flip |
+ |:---:|:-------:|:---------------------------------------|
+ | 0 | 90 Counterclockwise and verfical flip (default) |
+ | 1 | 90 Clockwise |
+ | 2 | 90 CounterClockwise |
+ | 3 | 90Clockwise and vertical flip |
tag: vision
tag: video
shell: sh
aim: Translate a media file to a new type
cmd: ffmpeg -formats
+ ffmpeg -i ${input} ${output}
bin: ffmpeg
tag: vision
tag: music
tag: video
shell: sh
aim: Reduce video quality
cmd: quality=20
+ ffmpeg -i ${input}.mp4 -vcodec libx264 -crf ${quality} ${output}.mp4
note: A crf quality of 18 is high, while 24 is low quality.
bin: ffmpeg
tag: vision
tag: video
shell: sh
aim: Convert from mkv to mp4 with a codec
cmd: ffmpeg -i ${input}.mkv -codec copy ${output}.mp4
note: Both mp4 and mkv are wrappers around other formats, so this conversion loses less quality than other conversion types.
bin: ffmpeg
tag: vision
tag: video
shell: sh
aim: Convert video to audio
cmd: ffmpeg -i ${input}.mp4 -vn ${output}.mp3
bin: ffmpeg
tag: vision
tag: video
shell: sh
aim: Convert all mkv files to mp4
cmd: for i in *.mkv; do
+ ffmpeg -i "$i" -codec copy "${i%.*}.mp4"
+ done
bin: ffmpeg
tag: vision
shell: sh
aim: Change resolution
cmd: ffmpeg -i ${input}.mp4 -filter:v scale=1280:720 -c:a copy ${output}.mp4
bin: ffmpeg
tag: vision
shell: sh
aim: Change video aspect ratio
cmd: ffmpeg -i input.mp4 -aspect 16:9 output.mp4
bin: ffmpeg
tag: vision
tag: video
shell: sh
aim: Trim video to start and stop times
cmd: start=00:00:50
+ stop=50
+ ffmpeg -i ${input}.mp4 -ss ${start} -codec copy -t ${stop} ${output}.mp4
note: The `$stop` time shows how many seconds after the start you want.
bin: ffmpeg
tag: vision
shell: sh
aim: Compress a video file
cmd: quality=21
+ ffmpeg -i ${input}.mp4 -vf scale=1280:-1 -c:v libx264 -preset veryslow -crf ${quality} ${output}.mp4
note: A crf quality of 18 is high, while 24 is low quality.
bin: ffmpeg
tag: vision
tag: video
shell: sh
aim: Convert video to a series of images
cmd: framerate=1
+ format=image2
+ ffmpeg -i input.mp4 -r ${framerate} -f ${format} image-%2d.png
bin: ffmpeg
tag: vision
shell: sh
aim: Add subtitles to a video file
cmd: fmpeg -i ${input}.mp4 -i subtitle.srt -map 0 -map 1 -c copy -c:v libx264 -crf 23 -preset veryfast ${output}.mp4
bin: ffmpeg
tag: vision
shell: sh
aim: Convert a web page to markdown
cmd: curl -sL "${url}" | html2markdown > "${file}}".md
cmd: curl -sL "${url}" | html2text > "${file}}".md
note: The `[html2markdown](https://github.com/JohannesKaufmann/html-to-markdown)` and `html2md` programs works better than any other.
bin: html2markdown
bin: curl
tag: writing
tag: web
shell: sh
aim: Decode a URL with function
cmd: urldecode() { echo -e "${@//%/\\x}"; }
+ urldecode "${magnet}"
tag: web
shell: bash
aim: Request a definition from the terminal.
cmd: word='abderian'
+ curl -s dict://dict.org/define:${word}:
cmd: function wotsa(){
+ def="$(curl -s dict://dict.org/define:${1// /+}: | grep -vP '^\d\d\d ')"
+ if [ "$def" = "" ]; then
+ echo no definition
+ else
+ echo "$def" | $PAGER
+ fi
+ }
bin: curl
tag: writing
tag: comfy
tag: dict
shell: sh

View File

@@ -4,7 +4,7 @@ tags:
- data - data
- setup - setup
requires: requires:
- git - data/git.md
--- ---

View File

@@ -4,7 +4,7 @@ tags:
- data - data
- git - git
requires: requires:
- git - data/git.md
--- ---
You can make Alice the author, while you are still the commiter: You can make Alice the author, while you are still the commiter:

View File

@@ -4,7 +4,7 @@ tags:
- data - data
- git - git
requires: requires:
- git - data/git.md
--- ---
Git Large File Storage ('LFS') needs to change your `~/.gitconfig` to check out those binary files: Git Large File Storage ('LFS') needs to change your `~/.gitconfig` to check out those binary files:

View File

@@ -4,7 +4,7 @@ tags:
- data - data
- git - git
requires: requires:
- git - data/git.md
--- ---
Save file-changes without committing anything. Save file-changes without committing anything.

View File

@@ -5,8 +5,8 @@ tags:
- secrets - secrets
- TUI - TUI
requires: requires:
- gpg - data/gpg.md
- vim - writing/vim.md
--- ---

View File

@@ -4,10 +4,10 @@ tags:
- vim - vim
- data - data
- gpg - gpg
requires:
- gpg
- vim
- comfy - comfy
requires:
- data/gpg.md
- writing/vim.md
--- ---
The `vim-gnupg` plug-in lets vim edit gpg-encrypted files as if they were unencrypted. The `vim-gnupg` plug-in lets vim edit gpg-encrypted files as if they were unencrypted.

View File

@@ -1,7 +1,8 @@
--- ---
title: groff title: groff
tags: tags:
- data - documentation
- typography
- logic - logic
--- ---
# Basic Documents # Basic Documents
@@ -62,8 +63,6 @@ The equation shorthands are predictable:
| Not equal | != | | Not equal | != |
| Superscript | sup {thing} | | Superscript | sup {thing} |
- [List of symbols](https://www.math-linux.com/man/man7/groff_char.7.html)
### Examples ### Examples
The fraction 2/5ths: The fraction 2/5ths:

View File

@@ -13,7 +13,7 @@ mkdir ~/.config/newsboat
echo 'https://voidlinux.org/atom.xml foss tech' >> ~/.config/newsboat/urls echo 'https://voidlinux.org/atom.xml foss tech' >> ~/.config/newsboat/urls
``` ```
Start `newsobat` and press `r` to load your feed. Start `newsboat` and press `r` to load your feed.
To add a feed, you can press `E` to edit that `urls` file. To add a feed, you can press `E` to edit that `urls` file.

View File

@@ -5,7 +5,7 @@ tags:
- credentials - credentials
- secrets - secrets
requires: requires:
- gpg - data/gpg.md
--- ---
Setup [gpg](gpg.md) keys. Setup [gpg](gpg.md) keys.

View File

@@ -7,7 +7,7 @@ tags:
- 2fa - 2fa
- otp - otp
requires: requires:
- pass - data/pass.md
--- ---
Need a Microsoft or Google authenticator? Need a Microsoft or Google authenticator?

View File

@@ -1,25 +0,0 @@
#!/bin/bash
pdftoppm -png input.pdf page
for x in *png; do
tesseract -l eng "$x" - >> out.tex
done
rm *png
sed -i -ze :a -e 's/\([a-z]\)\(-\)\n\+\([a-zA-Z]\)/\1\3/g' out.tex
sed -i -ze :a -e 's/\([a-z]\)\n\+\([a-zA-Z]\)/\1 \2/g' out.tex
sed -i -ze :a -e 's/\([A-Z]\){3}\+\n/\1 XYZ/g' out.tex
sed -i -ze :a -e 's/\n\([A-Z]\{3\}\+\)\n/\\section{\1}\n/g' out.tex
sed -i -ze :a -e 's/\([a-z]\)\. \([A-Z]\)/\1\.\n\2/g' out.tex
sed -i 's/“//g' out.tex
sed -i "s/”/''/g" out.tex
sed -i "s//'/g" out.tex
sed -i "s//'/g" out.tex
sed -i "s/\.''/''\./g" out.tex
sed -i "s/ — / -- /g" out.tex
sed -i 's/\$/\\$/g' out.tex
sed -i 's/%/\\%/g' out.tex
sed -i 's/&/\\&/g' out.tex

View File

@@ -4,7 +4,7 @@ tags:
- metadata - metadata
- ghost script - ghost script
- gs - gs
- .pdf - pdf
--- ---
You cannot erase pdf metadata with `exiftool` (it only *appends* your changes). You cannot erase pdf metadata with `exiftool` (it only *appends* your changes).

View File

@@ -4,8 +4,7 @@ tags:
- data - data
- calendar - calendar
requires: requires:
- nginx - networking/nginx.md
- certbot
--- ---
Check before you start: Check before you start:

View File

@@ -6,9 +6,9 @@ tags:
- recfiles - recfiles
- tex - tex
requires: requires:
- recfiles - data/recfiles.md
- tex - writing/tex.md
- makefiles - system/makefiles.md
--- ---
Store your bibliography in a `recfile` database, then extract any part with `make`. Store your bibliography in a `recfile` database, then extract any part with `make`.

View File

@@ -5,7 +5,7 @@ tags:
- recfiles - recfiles
- games - games
requires: requires:
- recfiles - data/recfiles.md
--- ---
You can play with a board games database from boardgamegeek.com. You can play with a board games database from boardgamegeek.com.

View File

@@ -5,7 +5,7 @@ tags:
- database - database
- recfiles - recfiles
requires: requires:
- recfiles - data/recfiles.md
--- ---
## Create ## Create

View File

@@ -4,7 +4,8 @@ tags:
- data - data
- recfiles - recfiles
- games - games
requires: recfiles requires:
- data/recfiles.md
--- ---
## Download the Database ## Download the Database

View File

@@ -5,8 +5,8 @@ tags:
- recfiles - recfiles
- logs - logs
requires: requires:
- recfiles - data/recfiles.md
- nginx - networking/nginx.md
--- ---
The standard `nginx` log format has such a lack of consistency or meaning that you might squint your face into a whirlpool making sense of them: The standard `nginx` log format has such a lack of consistency or meaning that you might squint your face into a whirlpool making sense of them:

View File

@@ -4,7 +4,7 @@ tags:
- data - data
- recfiles - recfiles
requires: requires:
- recfiles - data/recfiles.md
--- ---
Sometimes `recsel` chokes on a large query, and you need to break the query into chunks with a pipe. Sometimes `recsel` chokes on a large query, and you need to break the query into chunks with a pipe.

View File

@@ -6,7 +6,7 @@ tags:
- spreadsheet - spreadsheet
- csv - csv
requires: requires:
- vim - writing/vim.md
--- ---
- [Sample file](sc-im/sample.sc) - [Sample file](sc-im/sample.sc)

View File

@@ -5,7 +5,8 @@ tags:
- search - search
- locate - locate
- plocate - plocate
requires: cron requires:
- system/cron.md
--- ---
You can search every file on the computer instantly by installing `plocate`. You can search every file on the computer instantly by installing `plocate`.

View File

@@ -6,8 +6,8 @@ tags:
- lfs - lfs
- TUI - TUI
requires: requires:
- git - data/git.md
- nginx - networking/nginx.md
--- ---
- [Soft-Serve with https](soft-serve/soft_https.md) - [Soft-Serve with https](soft-serve/soft_https.md)

View File

@@ -5,8 +5,8 @@ tags:
- git server - git server
- lfs - lfs
requires: requires:
- git - data/git.md
- nginx - networking/nginx.md
--- ---
## `http` Setup ## `http` Setup

View File

@@ -5,8 +5,8 @@ tags:
- git server - git server
- maintenance - maintenance
requires: requires:
- git - data/git.md
- nginx - networking/nginx.md
--- ---
Over time git repositories become bloated with old data, but never get cleaned. Over time git repositories become bloated with old data, but never get cleaned.

View File

@@ -4,7 +4,7 @@ tags:
- backups - backups
- synch - synch
requires: requires:
- ssh - networking/ssh.md
--- ---
Install unison on both machines, and make sure both have the same version of unison, with the same version of the ocaml compiler (the smallest difference will cause problems). Install unison on both machines, and make sure both have the same version of unison, with the same version of the ocaml compiler (the smallest difference will cause problems).

View File

@@ -3,7 +3,7 @@ title: Install Arch
tags: tags:
- arch - arch
requires: requires:
- partitions - system/partitions.md
--- ---
Keyboard layout changed. Keyboard layout changed.

View File

@@ -3,7 +3,8 @@ title: Install yay
tags: tags:
- distros - distros
- arch - arch
requirements: [ "pacman" ] requires:
- distros/arch/basic_install.md
--- ---
```sh ```sh
@@ -17,14 +18,14 @@ The flags are mostly the same as in `pacman`.
But running `yay` without flags will do the update like `yay -Syu` and with package name it will search packages in the AUR and `pacman` repos, and let you choose which to install. But running `yay` without flags will do the update like `yay -Syu` and with package name it will search packages in the AUR and `pacman` repos, and let you choose which to install.
```sh ```sh
yay <search_term> yay ${search_term}
``` ```
Building the package can usually take some time, and after the build it will ask for the `sudo` password. Building the package can usually take some time, and after the build it will ask for the `sudo` password.
If you leave, the installation will fail. If you leave, the installation will fail.
To avoid this, you can use the flag `--sudoloop` and enter the sudo password initially and it will loop it until the installation is finished. To avoid this, you can use the flag `--sudoloop` and enter the `sudo` password initially and it will loop it until the installation is finished.
```sh ```sh
yay -S --noconfirm --sudoloop <package_name> yay -S --noconfirm --sudoloop ${package_name}
``` ```

View File

@@ -2,7 +2,9 @@
title: Arch Maintenance title: Arch Maintenance
tags: tags:
- arch - arch
requirements: [ "pacman" ] requires:
- pacman
- vim
--- ---
# Package Cache # Package Cache

View File

@@ -2,7 +2,8 @@
title: pacman title: pacman
tags: tags:
- distros - distros
requirements: [ "Install Arch" ] requires:
- distros/arch/basic_install.md
--- ---
Packages are kept in /var/cache/pacman/pkg. Packages are kept in /var/cache/pacman/pkg.

View File

@@ -2,7 +2,8 @@
title: pacman - Extras title: pacman - Extras
tags: tags:
- distros - distros
requirements: [ "pacman" ] requires:
- distros/arch/pacman.md
--- ---
## Unattended Actions ## Unattended Actions
@@ -24,7 +25,7 @@ You can tell `pacman` that this is a dependency for another package:
```sh ```sh
pacman -S --noconfirm --asdeps <weird music player> pacman -S --noconfirm --asdeps ${weird_music_player}
``` ```
When you [remove orphaned packages](pacman.md), the package will be automatically uninstalled. When you [remove orphaned packages](pacman.md), the package will be automatically uninstalled.

View File

@@ -1,13 +1,15 @@
--- ---
title: Arch Maintenance with yay title: Arch maintenance with yay
tags: tags:
- arch - arch
requirements: [ "Arch Maintenance" ] - maintenance
requires:
- distros/arch/maintenance.md
--- ---
# Package Cache # Package Cache
Just like `pacman` Just like `[pacman](distros/arch/pacman.md)` with a couple of extras.
```sh ```sh
ls ~/.cache/yay/ | wc -l ls ~/.cache/yay/ | wc -l

View File

@@ -2,34 +2,53 @@
title: Void Autologin title: Void Autologin
tags: tags:
- void - void
- autologin
--- ---
Make the autologin service: The virtual terminals are run as services.
Make a new service by making symbolic links to the generic one.
```sh ```sh
cp -R /etc/sv/agetty-tty1 /etc/sv/agetty-autologin-tty1 login=agetty-autologin
sudo cp -rs /etc/sv/agetty-generic/ /etc/sv/${login}/
``` ```
Copy the configuration file for the `agetty-tty1` service, and add the `--autologin` argument.
```sh ```sh
sed "s/--noclear/--autologin ${USER} &/" /etc/sv/agetty-tty1/conf | sudo tee /etc/sv/${login}/conf
```
It should look like this:
```
if [ -x /sbin/agetty -o -x /bin/agetty ]; then if [ -x /sbin/agetty -o -x /bin/agetty ]; then
# util-linux specific settings # util-linux specific settings
if [ "${tty}" = "tty1" ]; then if [ "${tty}" = "tty1" ]; then
GETTY_ARGS="--noclear" GETTY_ARGS="--autologin ${your_username} --noclear"
fi fi
fi fi
GETTY_ARGS="--autologin [ your username ] --noclear"
BAUD_RATE=38400
TERM_NAME=linux
``` ```
Then stick this at the end of the bashrc: If you see the actual variable `${USER}` then you probably used the wrong quotes.
Disable the `tty1` service (because the login takes its place).
```sh ```sh
# autologin on tty1 sudo touch /etc/sv/agetty-tty1/down
if [ -z "$DISPLAY" ] && [ "$(fgconsole)" -eq 1 ]; then
exec startx
fi
``` ```
Enable your `${login}` service:
```sh
sudo ln -s /etc/sv/${login} /var/service/
```
Reboot.
Pizza party for one.

View File

@@ -1,7 +1,39 @@
%rec: example %rec: example
%key: filename
%type: note line
filename: default.service
bin: systemd
usage: mv {{filename}} /usr/lib/systemd/system/
+ systemctl daemon-reload
+ systemctl enable --now {{filename}}
note: Basic systemd service file
content: [Unit]
+
+ Description={{script}}
+
+ [Service]
+
+ ExecStart=/home/{{user}}/.local/bin/{{script}}.sh
+
+ Restart=always
+
+ Type=simple
+
+ User={{user}}
+
+ Group={{group}}
+
+ [Install]
+
+ WantedBy=multi-user.target
+
+ Alias=test.service
+
filename: food.sc filename: food.sc
bin: sc-im bin: sc-im
usage: {{bin}} {{filename}}
note: Basic sc-im example of adding and averaging note: Basic sc-im example of adding and averaging
content: # This data file was generated by the Spreadsheet Calculator Improvised (sc-im) content: # This data file was generated by the Spreadsheet Calculator Improvised (sc-im)
+ # You almost certainly shouldn't edit it. + # You almost certainly shouldn't edit it.
@@ -48,3 +80,43 @@ content: # This data file was generated by the Spreadsheet Calculator Improvised
+ pad 2 B6 + pad 2 B6
+ pad 4 A10 + pad 4 A10
+ goto A10 + goto A10
filename: lowdown.mk
bin: make
usage: {{bin}} -f {{filename}}
content: output: all
+
+ .PHONY: example
+ example: html/foot.html html/head.html
+ mkdir -p articles/
+ fortune > articles/fort_1.md
+ fortune > articles/fort_2.md
+
+ HTML = $(patsubst articles/%.md,public/%.html,$(wildcard articles/*.md))
+
+ $(HTML): public/ articles/ $(wildcard html/*)
+
+ html/head.html:
+ @mkdir $(@D)
+ echo '<head> Something about CSS probably </head>' > $@
+ echo '<body>' >> $@
+
+ html/foot.html: html/head.html
+ echo '</body>' >> $@
+
+ public/%.html : articles/%.md
+ cat html/head.html > $@
+ lowdown $< >> $@
+ cat html/foot.html >> $@
+
+ .PHONY: all
+ all : $(HTML)
+
+ articles/:
+ mkdir $@
+
+ public/:
+ mkdir $@
+
+ clean :
+ rm -rf public html

View File

@@ -4,3 +4,5 @@
```{{shell}} ```{{shell}}
{{cmd}} {{cmd}}
``` ```
{{note}}

View File

@@ -4,6 +4,8 @@ tags:
- networking - networking
- arch - arch
- gemini - gemini
requires:
- distros/arch/install_yay.md
--- ---
Docs are [here](https://github.com/mbrubeck/agate). Docs are [here](https://github.com/mbrubeck/agate).
@@ -54,7 +56,7 @@ agate --content $GEMDIR --certs $GEMDIR/.certs \
Once that works, it's time to make a service file; select any name for it: Once that works, it's time to make a service file; select any name for it:
`SVFILE=st` `${svfile}=st`
``` ```
echo " echo "
@@ -63,27 +65,27 @@ CERT=--certs $GEMDIR/.certs
ADDR=--addr [::]:1965 --addr 0.0.0.0:1965 ADDR=--addr [::]:1965 --addr 0.0.0.0:1965
HOSTNAME=--hostname $DOMAIN1 --hostname $DOMAIN2 HOSTNAME=--hostname $DOMAIN1 --hostname $DOMAIN2
LANG=--lang $LANG LANG=--lang $LANG
" > $SVFILE.conf " > ${svfile}.conf
``` ```
Check the service file has all those variables and looks right: Check the service file has all those variables and looks right:
`cat $SVFILE.conf` `cat ${svfile}.conf`
Now move it into the agate config directory: Now move it into the agate config directory:
`mv $SVFILE.conf /etc/agate/` `mv ${svfile}.conf /etc/agate/`
And finally, start the service: And finally, start the service:
``` ```
systemctl daemon-reload systemctl daemon-reload
systemctl enable --now agate@$SVFILE.conf systemctl enable --now agate@${svfile}.conf
``` ```
Your Gemini capsule should be available, and you should be able to see any access in the logs: Your Gemini capsule should be available, and you should be able to see any access in the logs:
``` ```
journalctl -xeu agate@$SVFILE.conf journalctl -xeu agate@${svfile}.conf
``` ```

View File

@@ -1,5 +1,5 @@
--- ---
title: dns title: DNS Record List
tags: tags:
- networking - networking
- host - host
@@ -12,10 +12,9 @@ tags:
| CNAME | Alternative Address | "$domain".rs, "$subdomain.$domain".com | | CNAME | Alternative Address | "$domain".rs, "$subdomain.$domain".com |
| NS | Nameserver | ns1.fastname.com | | NS | Nameserver | ns1.fastname.com |
| MX | Email server | "$domain".com | | MX | Email server | "$domain".com |
| TXT | Literally anything,including ownership of a domain | | | TXT | Literally anything,including ownership of a domain | - |
| | | |
Query a host with the `host` command. Query a host's IP and email handlers with the `host` command.
```sh ```sh
host $domain.$tld host $domain.$tld

View File

@@ -3,7 +3,7 @@ title: fail2ban
tags: tags:
- networking - networking
requires: requires:
- ssh - networking/ssh.md
--- ---
# SSH Daemon Jail # SSH Daemon Jail

44
networking/nat_check.md Normal file
View File

@@ -0,0 +1,44 @@
---
title: Check if NAT-blocked
tags:
- networking
- nat
---
Trace the route to any domain name.
```sh
traceroute to splint.rs (89.216.117.22), 30 hops max, 60 byte packets
1 _gateway (192.168.0.1) 0.265 ms 0.209 ms 0.193 ms
2 100.64.0.1 (100.64.0.1) 56.974 ms 60.893 ms 60.911 ms
3 172.31.254.2 (172.31.254.2) 61.795 ms 61.610 ms 70.443 ms
4 172.31.254.2 (172.31.254.2) 69.929 ms 69.948 ms 71.265 ms
5 bg-tp-m-0-be4-100.sbb.rs (89.216.12.0) 72.890 ms 73.268 ms *
6 bg-ne-m-10-be3.sbb.rs (89.216.6.76) 78.474 ms 77.306 ms 77.821 ms
7 * bg-tp-m-11-be1.sbb.rs (89.216.6.75) 35.022 ms bg-tp-m-12-be1.sbb.rs (89.216.6.77) 63.808 ms
8 89.216.4.63 (89.216.4.63) 63.753 ms 89.216.4.61 (89.216.4.61) 65.546 ms 67.876 ms
9 * * *
10 * * *
11 * * *
12 * * *
13 * * *
1
```
The first hop goes to a router (`192.`...).
The second hop looks like an internal address, so I'm going to double-check.
```sh
address=100.64.0.1
curl -s http://api.db-ip.com/v2/free/$address
{
"ipAddress": "100.64.0.1",
"countryCode": "ZZ"
}
```
That's not a real country code, so the second hop passes through something with an [internal address][internalIPs] after the router.
It looks like this connection has a [NAT layer][natIPs].
[internalIPs]: https://en.wikipedia.org/wiki/List_of_reserved_IP_addresses
[natIPs]: https://en.wikipedia.org/wiki/Carrier-grade_NAT

View File

@@ -12,9 +12,9 @@ nmap 192.168.1.1/24
Flags: Flags:
| Flag | Meaning | Effect | | Flag | Meaning | Effect |
| :---| :---| :---| |:-----|:--------|:---------------------|
| -F | Fast | First 100 ports only | | -F | Fast | First 100 ports only |
Look for a web server, which has ports 80 and 443 open: Look for a web server, which has ports 80 and 443 open:

View File

@@ -3,7 +3,7 @@ title: sshfs
tags: tags:
- networking - networking
requires: requires:
- ssh - networking/ssh.md
--- ---
# Mount # Mount

View File

@@ -5,7 +5,7 @@ tags:
- ssh - ssh
- tricks - tricks
requires: requires:
- ssh - networking/ssh.md
--- ---
Mount a remote filesystem locally with fuse-sshfs: Mount a remote filesystem locally with fuse-sshfs:

1
required.fmt Normal file
View File

@@ -0,0 +1 @@
- ({{requires_title}})[{{requires}}]

45
shell/options.md Normal file
View File

@@ -0,0 +1,45 @@
---
title: Give shell script options
tags:
- shell
- script
requires: shell/scripts.md
---
Place this in a file called `options.sh`, and make it executable.
```sh
#!/bin/sh
echo "This script is called $0"
while getopts oe: choice ; do
case "$choice" in
o)
echo "This is option number '${OPTIND}'."
;;
e) echo "Option number '${OPTIND}' uses this variable: '${OPTARG}'."
;;
\?) echo "That's not an option."
exit 1
;;
esac
done
shift "$(($OPTIND -1))"
echo "The standard arguments are: $@"
```
Try the options:
```sh
./options.sh -o
./options.sh -e elephant
./options.sh Some random words
./options.sh -efox Some other words
```
Try the script again, without the `shift` statement.
**NB:** You can change `choice` to any variable, but you must use `OPTARG` to show an option's argument and `OPTIND` to show the index of that argument.

View File

@@ -2,9 +2,10 @@
title: Use the terminal in vi-mode title: Use the terminal in vi-mode
tags: tags:
- shell - shell
- vi - vim
- comfy - comfy
- readline - readline
- python
--- ---
# Vi-Commands # Vi-Commands

17
shell/scripts.md Normal file
View File

@@ -0,0 +1,17 @@
---
title: Making Scripts
tags:
- shell
---
Make a script for your regular shell commands.
```sh
name=look
echo '#!/bin/sh > ${name}.sh
echo 'echo "This script is called $0"'
chmod u+x !$
./!$
```
Notice the single-quotes, *not* double quotes.

View File

@@ -3,7 +3,8 @@ title: mpd with pipewire
tags: tags:
- sound - sound
- pipewire - pipewire
requirements: [ "pipewire" ] requires:
- sound/pipewire.md
--- ---
# Setup # Setup

View File

@@ -5,8 +5,8 @@ tags:
- ansible - ansible
- orchestration - orchestration
requires: requires:
- ssh - networking/ssh.md
- pass - data/pass.md
--- ---
# Start Locally # Start Locally

View File

@@ -5,8 +5,8 @@ tags:
- ansible - ansible
- docker - docker
requires: requires:
- docker - virtualization/docker.md
- ansible - system/ansible.md
--- ---
'Docker module', you say? 'Docker module', you say?

View File

@@ -2,7 +2,7 @@
title: awk title: awk
tags: tags:
- system - system
- .csv - csv
--- ---
# Basics # Basics

View File

@@ -7,33 +7,46 @@ tags:
Check which groups you are in, and which are available: Check which groups you are in, and which are available:
```sh ```sh
cat /etc/group
groups groups
cat /etc/group | grep $USER cat /etc/group
column -ts: /etc/group
grep $USER !$
``` ```
Remove yourself from all groups, and add yourself back to only `wheel`, `audio`, and your own group: Remove yourself from all groups, and add yourself back to only `mail`, `audio`, and your own group:
```sh ```sh
sudo usermod --groups wheel,audio,$USER sudo usermod --groups mail,audio,$USER
``` ```
Add yourself to the `docker` group: Add yourself to the `docker` group, if there is one:
```sh ```sh
su root -c "usermod --append --groups docker $USER" grep docker /etc/group
sudo usermod --append --groups docker $USER
``` ```
Add yourself to the `network` group:
Add yourself to the `games` group:
```sh ```sh
sudo usermod -aG network $USER sudo usermod -aG games $USER
``` ```
You are now legally permitted to play [games](shell/games.md).
The changes have not taken effect, so log into your own account again with `su`: The changes have not taken effect, so log into your own account again with `su`:
```sh ```sh
groups groups
sudo su $USER grep audio /etc/group
sudo usermod -aG audio $USER
groups groups
grep audio /etc/group
su $USER
groups
grep audio /etc/group
``` ```

View File

@@ -1,13 +1,13 @@
--- ---
title: Python Projects with Makefiles title: Python Projects with Makefiles
tags: tags:
- tutorial - setup
- system - system
- makefiles - makefiles
- graphviz - graphviz
- python - python
requires: requires:
- makefiles - system/makefiles.md
--- ---
If you have a python script which requires a packages - e.g. `graphviz` - you can automate the setup with a `Makefile`. If you have a python script which requires a packages - e.g. `graphviz` - you can automate the setup with a `Makefile`.

View File

@@ -1,35 +0,0 @@
---
title: systemd
tags:
- systemd
---
```sh
systemctl list-units
```
```sh
sudo systemctl status mpd
```
```sh
sudo systemctl daemon-reload
```
```sh
sudo systemctl taskd.service start
```
```sh
sudo systemctl status taskd.service
```
# Startup
```sh
sudo systemd-analyze
```
```sh
sudo systemd-analyze blame
```

View File

@@ -1,45 +0,0 @@
---
title: journal
tags:
- systemd
---
See a running log of all system messages:
```sh
journalctl -f
```
Or just one user:
```sh
journalctl --user -f
```
Or just one unit (`sshd`):
```sh
journalctl -f -u sshd
```
Find errors since November
```sh
journalctl --since=2018-11-01 --grep="EXT4-fs error"
```
Limit size to 2G.
```sh
journalctl --vacuum-size=2G
```
Log the fact that you've installed your own `dnsmasq` on your system to `journalctl`, so that you can notice why your system's broken:
```sh
logger "Installed new dnsmasq"
sudo journalctl -f
```

View File

@@ -1,13 +1,23 @@
--- -
title: Making Services title: Making Services
tags: tags:
- systemd - systemd
--- ---
# Basics
A service can consist of two files - the .sh script to run, and the .service file which describes its run conditions. A service can consist of two files - the script to run (usually a shell
script), and the `.service` file which describes when it runs.
The .service file goes in /etc/systemd/system. The scripts themselves might be best placed in $HOME/.local/bin. The service file goes into the memorably-named directory `/usr/lib/systemd/system/`, where `systemd` will not notice your new service file.
Try not to confuse this with `/usr/share/systemd/` or `/var/lib/systemd/`, but *do*
To make a formal introduction between `systemd` and your service file, reload the daemon and check the list of units.
```sh
sudo systemctl daemon-reload
sudo systemctl list-units | grep ${service}
```
Once you enable the service, `systemd` makes a symbolic link from `/usr/lib/systemd/system/` to `/etc/systemd/system/`.
# Example - tracker.service # Example - tracker.service
@@ -21,18 +31,10 @@ ExecStart=/path/to/script
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
After making the new service, systemd requires reloading: ## Types
```sh * `simple` - the service runs forever. Other services do not stop it.
sudo systemctl daemon-reload * `oneshot` - the service executes once, then stops.
```
# Types
* simple - the service cannot be called on by others. It runs on repeat.
* oneshot - the service executes once, then stops.

View File

@@ -1,23 +0,0 @@
[Unit]
Description=Test
[Service]
ExecStart=/home/ghost/.local/bin/test
Restart=always
Type=simple
User=ghost
Group=ghost
[Install]
WantedBy=multi-user.target
Alias=test.service

View File

@@ -4,8 +4,9 @@ tags:
- documentation - documentation
- virtualization - virtualization
requires: requires:
- groups - system/groups.md
--- ---
```sh ```sh
sudo pacman -S docker sudo pacman -S docker
``` ```
@@ -21,7 +22,7 @@ sudo systemctl start docker
You need to either log out and back in again to be in the docker group, or run everything as root. You need to either log out and back in again to be in the docker group, or run everything as root.
```sh ```sh
# docker info docker info | less -Ri
``` ```
This should show you things are working. This should show you things are working.

View File

@@ -4,7 +4,7 @@ tags:
- virtualization - virtualization
- kubernetes - kubernetes
requires: requires:
- minikube_setup - virtualization/kubernetes/minikube_setup.md
--- ---
Install `kubectl`. Install `kubectl`.

View File

@@ -3,11 +3,11 @@ title: Kubernetes Docs
tags: tags:
- virtualization - virtualization
- kubernetes - kubernetes
- WTFM - wtfm
- hosts - hosts
- DNS - dns
requires: requires:
- minikube_setup - virtualization/kubernetes/minikube_setup.md
--- ---
`kubectl` provides easy high-level overviews: `kubectl` provides easy high-level overviews:
@@ -25,7 +25,7 @@ The `kubectl explain` resources cannot use tab-completion.
But you can find the same resources listed with `api-resources`, and use a fuzzy-finder, to get the same effect. But you can find the same resources listed with `api-resources`, and use a fuzzy-finder, to get the same effect.
```sh ```sh
t="$(kubectl api-resources | fzy | gawk '{print $1}')" t="$(kubectl api-resources | fzf | gawk '{print $1}')"
kubectl explain ${t} kubectl explain ${t}
``` ```

View File

@@ -4,10 +4,12 @@ tags:
- virtualization - virtualization
- kubernetes - kubernetes
- minikube - minikube
- docker requires:
- virtualization/docker.md
--- ---
# Install `minikube` # Install `minikube`
Set up a practice environment with `minikube`, using either Docker or VirtualBox. Set up a practice environment with `minikube`, using either Docker or VirtualBox.
1. Install the driver (VirtualBox is a good choice). 1. Install the driver (VirtualBox is a good choice).

View File

@@ -4,7 +4,7 @@ tags:
- virtualization - virtualization
- kubernetes - kubernetes
requires: requires:
- minikube_setup - virtualization/kubernetes/minikube_setup.md
--- ---
Start the proxy: Start the proxy:

View File

@@ -3,7 +3,7 @@ title: virtualbox
tags: tags:
- system - system
requires: requires:
- groups - system/groups.md
--- ---
# Setup # Setup

View File

@@ -1,169 +0,0 @@
---
title: ffmpeg
tags:
- sound
- vision
---
# Basics
Translate a media file to a new type.
ffmpeg -i [input file] output_file.mkv
The input file might be a device, such as a camera.
# Record screen
Take the format as 'grab the x11 screen'.
```sh
ffmpeg -f x11grab -s [screensize] -i :0.0 out.mkv
```
Get screensize with
```sh
xrandr -q
```
or maybe just...
```sh
ffmpeg -f x11grab -s "$(xdpyinfo | grep dimensions | awk '{print $2}')" -i :1.0 out.mkv
```
# Add default pulse audio
```sh
ffmpeg -f x11grab -s [screensize] -i :0.0 -f alsa -i default out.mkv
```
For problems, see pavucontrol.
# Random online suggestion
ffmpeg -video_size "$(xdpyinfo | grep dimensions | awk '{print $2}')" -f x11grab -i :0.0 -f pulse -ac 2 -i default ~/out.mkv
# Rotate
```sh
ffmpeg -i in.mov -vf "transpose=1" out.mov
```
0 = 90 Counterclockwise and verfical flip (default)
1 = 90 Clockwise
2 = 90 CounterClockwise
3 = 90Clockwise and vertical flip
# Lower Video Quality
A crf quality of 18 is high, while 24 is low quality.
ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4
# convert
Check for supported formats:
```sh
ffmpeg -formats
```
To convert from mkv to mp4 we can use a codec rather than proper conversion. Both are wrappers around other formats, so this conversion loses less quality than other conversion types.
```sh
ffmpeg -i LostInTranslation.mkv -codec copy LostInTranslation.mp4
```
Opus to mp3
```sh
ffmpeg -i song.opus song.mp3
```
```sh
ffmpeg -i video.flv video.mpeg
```
```sh
ffmpeg -i input.webm -qscale 0 output.mp4
```
# Video to Audio
```sh
ffmpeg -i input.mp4 -vn output.mp3
```
# Convert all mkv files to mp4
```sh
for i in *.mkv; do
```
> ffmpeg -i "$i" -codec copy "${i%.*}.mp4"
```sh
done
```
# Change resolution
```sh
ffmpeg -i input.mp4 -filter:v scale=1280:720 -c:a copy output.mp4
```
Or just crop:
```sh
ffmpeg -i input.mp4 -filter:v "crop=w:h:x:y" output.mp4
```
Or aspect ratio:
```sh
ffmpeg -i input.mp4 -aspect 16:9 output.mp4
```
Or trim to start and stop times:
```sh
ffmpeg -i input.mp4 -ss 00:00:50 -codec copy -t 50 output.mp4
```
Indicate start times with -ss and time with -t in seconds.
Or split a video into parts:
```sh
ffmpeg -i input.mp4 -t 00:00:30 -c copy part1.mp4 -ss 00:00:30 -codec copy part2.mp4
```
# Compress Video
```sh
ffmpeg -i input.mp4 -vf scale=1280:-1 -c:v libx264 -preset veryslow -crf 24 output.mp4
```
# Extract Images from Video
-r sets the frame rate, and -f selects the format.
```sh
ffmpeg -i input.mp4 -r 1 -f image2 image-%2d.png
```
# Add Images to Audio
```sh
$ ffmpeg -loop 1 -i inputimage.jpg -i inputaudio.mp3 -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4
```
# Add Subtitles
```sh
fmpeg -i input.mp4 -i subtitle.srt -map 0 -map 1 -c copy -c:v libx264 -crf 23 -preset veryfast output.mp4
```

View File

@@ -1,116 +0,0 @@
---
title: imagemagick
tags:
- vision
---
Convert jpg to png.
```sh
magick image.jpg image.png
```
```sh
magick image.jpg -quality 50 image.jpg
```
'Quality' must be from 1 to 100.
```sh
magick -resize 50% image.jpg image2.jpg
```
Resizing only changes jpegs. Change a png with:
```sh
magick input.png png8:out.png
```
# Invert Colours
```sh
magick input.jpg output.jpg -negate
```
# Make Images Smaller
```sh
magick image.jpg -resize 25% output.jpg
```
# Trim images to border
This is generally used for transparent images.
```sh
magick -trim image.png output.png
```
Make the white of an image transparent.
```sh
magick -transparent white -fuzz 10% input.png output.png
```
The 'fuzz' option tells the computer that 'close to white' is fine. You might want to use 20% or higher fuzz.
## Dropshadow
```sh
`magick <input file> \( +clone -background black -shadow 50x8+0+5 \) +swap -background none -layers merge +repage <output file>`
```
# Convert every jpg in directory to png
```sh
mogrify -format png *.jpg
```
# Printing Words
# Mass magick
This script magicks all jpg files in a directory to svg.
```
for i in *jpg
do magick "$i" $(ls "$i" | sed s#jpg\$#svg#)
done
```
# SVG
The above script has crappy results.
It's better to use potrace.
```
$magick -flatten input.jpg output.ppm
$potrace -s output.ppm -o svgout.svg
```
# Writing Words
[docs](https://www.imagemagick.org/Usage/text/)
See your installed fonts:
```sh
magick -list font
```
Make an image showing day of the week:
```sh
magick -fill blue -font Sauce-Code-Pro-Semibold-Nerd-Font-Complete-Mono -gravity center -pointsize 79 label:$(date +%A) day.png
```
Make a meme:
```sh
magick inputmemeimage.png -font impact -fill white -pointsize 84 -stroke black -strokewidth 3 -gravity north -annotate +0+20 'TOP MEME TEXT' -gravity south -annotate +0+20 'BOTTOM MEME TEXT' outputmemeimage.png
```

View File

@@ -2,7 +2,7 @@
title: Markdown to PDF title: Markdown to PDF
tags: tags:
- markdown - markdown
- .pdf - pdf
- vision - vision
--- ---

View File

@@ -1,36 +0,0 @@
output: all
.PHONY: example
example: html/foot.html html/head.html
mkdir -p articles/
fortune > articles/fort_1.md
fortune > articles/fort_2.md
HTML = $(patsubst articles/%.md,public/%.html,$(wildcard articles/*.md))
$(HTML): public/ articles/ $(wildcard html/*)
html/head.html:
@mkdir $(@D)
echo '<head> Something about CSS probably </head>' > $@
echo '<body>' >> $@
html/foot.html: html/head.html
echo '</body>' >> $@
public/%.html : articles/%.md
cat html/head.html > $@
lowdown $< >> $@
cat html/foot.html >> $@
.PHONY: all
all : $(HTML)
articles/:
mkdir $@
public/:
mkdir $@
clean :
rm -rf public

View File

@@ -1,11 +1,11 @@
--- ---
title: Calendar title: Output a LaTeX Calendar
tags: tags:
- writing - writing
- tex - tex
- fun - fun
requires: requires:
- tex_packages - writing/tex/tex_packages.md
--- ---
```sh ```sh

View File

@@ -5,7 +5,7 @@ tags:
- completion - completion
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
Complete the word by searching for the *n*ext similar word: Complete the word by searching for the *n*ext similar word:

View File

@@ -6,7 +6,7 @@ tags:
- linewrap - linewrap
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
Wrap lines in a file to 80 characters with `gqG`. Wrap lines in a file to 80 characters with `gqG`.

View File

@@ -5,7 +5,7 @@ tags:
- navigation - navigation
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
| Move | Command | | Move | Command |

View File

@@ -7,7 +7,7 @@ tags:
- find - find
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
Search for the next and or previous occurrence of the word under your cursor with `*` and `#`. Search for the next and or previous occurrence of the word under your cursor with `*` and `#`.

View File

@@ -5,7 +5,7 @@ tags:
- learning - learning
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
1. Uninstall `vim`. 1. Uninstall `vim`.

View File

@@ -6,7 +6,7 @@ tags:
- inputrc - inputrc
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
Put bash in vim mode! Put bash in vim mode!

View File

@@ -4,7 +4,7 @@ tags:
- vim - vim
- TUI - TUI
requires: requires:
- vim - writing/vim.md
--- ---
| Command | Keys | | Command | Keys |