From 49e7930541b178c91c355dbfe0c3b5f1298df99a Mon Sep 17 00:00:00 2001 From: Malin Freeborn Date: Mon, 27 Apr 2026 01:30:33 +0200 Subject: [PATCH] REBIRTH --- .gitignore | 3 - Makefile | 116 +++--- README.md | 140 +++++-- chat/profanity_automation.md | 2 +- chat/wgetpaste.md | 6 + cmd.mk | 25 +- command.rec | 390 +++++++++++++++++- data/git/cleanup.md | 2 +- data/git/commit_for_another.md | 2 +- data/git/git-lfs.md | 2 +- data/git/git_stash.md | 2 +- data/gpg/gpg_pinentry.md | 4 +- data/gpg/vim_decryption.md | 6 +- data/groff.md | 5 +- data/newsboat.md | 2 +- data/pass.md | 2 +- data/pass_otp.md | 2 +- data/pdf-to-txt.sh | 25 -- data/pdf_erasure.md | 2 +- data/radicale.md | 3 +- data/recfiles/bibliography.md | 6 +- data/recfiles/board_games.md | 2 +- data/recfiles/extended.md | 2 +- data/recfiles/ip_asn.md | 3 +- data/recfiles/nginx_logs.md | 4 +- data/recfiles/recfixes.md | 2 +- data/sc-im.md | 2 +- data/search_system.md | 3 +- data/soft-serve.md | 4 +- data/soft-serve/soft_https.md | 4 +- data/soft-serve/soft_maintenance.md | 4 +- data/unison.md | 2 +- .../{basic-install.md => basic_install.md} | 2 +- distros/arch/install_yay.md | 9 +- distros/arch/maintenance.md | 4 +- distros/arch/pacman.md | 3 +- distros/arch/pacman_extras.md | 5 +- distros/arch/yay_maintenance.md | 8 +- distros/void/autologin.md | 53 ++- example.rec | 72 ++++ lists.fmt | 2 + networking/agate.md | 14 +- networking/dns.md | 7 +- networking/fail2ban.md | 2 +- networking/nat_check.md | 44 ++ networking/nmap.md | 6 +- networking/ssh/sshfs.md | 2 +- networking/ssh/tricks.md | 2 +- required.fmt | 1 + shell/options.md | 45 ++ shell/readline.md | 3 +- shell/scripts.md | 17 + sound/mpd_pipewire.md | 3 +- system/ansible.md | 4 +- system/ansible/ansible_with_docker.md | 4 +- system/awk.md | 2 +- system/groups.md | 31 +- system/makefiles/python_projects.md | 4 +- system/systemd.md | 35 -- system/systemd/journal.md | 45 -- system/systemd/making-services.md | 32 +- system/systemd/test.service | 23 -- virtualization/docker.md | 5 +- .../kubernetes/kubernetes_basics.md | 2 +- .../kubernetes/kubernetes_explain.md | 8 +- virtualization/kubernetes/minikube_setup.md | 4 +- virtualization/kubernetes/proxy_api.md | 2 +- virtualization/virtualbox.md | 2 +- vision/ffmpeg.md | 169 -------- vision/imagemagick.md | 116 ------ vision/lowdown.md | 2 +- vision/lowdown/example.txt | 36 -- writing/tex/calendar.md | 4 +- writing/vim/completion.md | 2 +- writing/vim/linewrap.md | 2 +- writing/vim/navigate.md | 2 +- writing/vim/subs.md | 2 +- writing/vim/vi.md | 2 +- writing/vim/vim_in_bash.md | 2 +- writing/vim/windows.md | 2 +- 80 files changed, 924 insertions(+), 703 deletions(-) delete mode 100644 .gitignore delete mode 100755 data/pdf-to-txt.sh rename distros/arch/{basic-install.md => basic_install.md} (98%) create mode 100644 networking/nat_check.md create mode 100644 required.fmt create mode 100644 shell/options.md create mode 100644 shell/scripts.md delete mode 100644 system/systemd.md delete mode 100644 system/systemd/journal.md delete mode 100644 system/systemd/test.service delete mode 100644 vision/ffmpeg.md delete mode 100644 vision/imagemagick.md delete mode 100644 vision/lowdown/example.txt diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b404c66..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.pdf -*.gif -*.jpeg diff --git a/Makefile b/Makefile index 9235a34..9aa5a55 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,16 @@ MAKEFLAGS += -j MAKEFLAGS += -s EDITOR ?= vi -FZF != command -v sk || command -v fzy || command -v fzf || \ - { echo install a fuzzy finder && exit 1 ;} +PAGER ?= less -Ri +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" FZF += -i -else - FZF += --print-query | tail -1 endif spill_contents = sed -e '1,/---/d' @@ -19,18 +22,9 @@ help: ## Print the help message articles != find * -type f -name "*.md" -dirs != ls -d */ -categories = $(patsubst %/, %, $(dirs)) - -databases = $(patsubst %, .dbs/%.rec, $(categories)) - -default += $(databases) -default += db.rec +default += .dbs/notes.rec default += .dbs/map.fmt -$(foreach dir, $(categories), \ - $(eval .dbs/$(dir).rec: $(wildcard $(dir)/*)) \ - ) %/: mkdir $@ @@ -38,34 +32,48 @@ $(foreach dir, $(categories), \ include cmd.mk -$(databases): .dbs/%.rec: %/ | .dbs/ - $(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 $? ) +.dbs/head.rec: | .dbs/ $(lists) 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: provides rec guide' >> $@ printf '%s\n' '%type: wordcount int' >> $@ printf '%s\n\n' '%sort: wordcount' >> $@ - cat $^ >> $@ - recsel $@ -e "requires != ''" -CR title,requires |\ - while read title requires; do \ - for provider in "$$requires" ; do \ - recset --verbose $@ -e "title = '$${provider}'" -f provides -a "$${title}" ;\ - done ;\ - done - sed -i 's/"//g' $@ - recfix --sort $@ - $(info Created main database: $@) + +.dbs/new.rec: $(wildcard */*.md */*/*.md) | .dbs/head.rec + $(info Updating: $?) + grep -q guide $@ 2>/dev/null || cp $| $@ + @-$(foreach entry, $?, \ + recdel -t guide $@ -e "path = '$(entry)'" 2>/dev/null ;\ + ) + for entry in $? ; do \ + echo '' ;\ + 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) @echo $^ | tr ' ' '\n' > $@ @@ -76,38 +84,40 @@ default += .git/info/exclude database: $(default) ## Make a recfiles database .dbs/map.fmt:| .dbs/ - printf '%s\n' '[ {{requires[0]}} ] --> [ {{title}} ] {border-style: dashed;}' > $@ - printf '%s\n' '[ {{requires[1]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ - printf '%s\n' '[ {{requires[2]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ - printf '%s\n' '[ {{requires[3]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ - printf '%s\n' '[ {{requires[4]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@ + printf '%s\n' '[ {{requires[0]}} ] --> [ {{path}} ] {border-style: dashed;}' > $@ + printf '%s\n' '[ {{requires[1]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@ + printf '%s\n' '[ {{requires[2]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@ + printf '%s\n' '[ {{requires[3]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@ + printf '%s\n' '[ {{requires[4]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@ .PHONY: map -map: db.rec .dbs/map.fmt ## Show knowledge dependency map - recsel -t guide $< -e 'requires != ""' -p title,requires | recfmt -f .dbs/map.fmt |\ - grep -vF '[ ]' | graph-easy --boxart | $${PAGER} +map: .dbs/requires.rec .dbs/map.fmt ## Show knowledge dependency map + recsel -t guide $< -e 'requires != ""' -p path,requires | recfmt -f .dbs/map.fmt |\ + grep -vF '[ ]' | graph-easy --boxart 2>/dev/null | ${PAGER} -S .PHONY: clean clean: ## Remove all generated files - $(RM) $(default) + $(RM) -r $(default) .dbs/ .PHONY: article -article: **/ **/**/ ## Write a new article - category=$(shell echo $^ | tr ' ' '\n' | $(FZF) ) \ +article: */ */*/ ## Write a new article + category=$(shell echo $^ | tr ' ' '\n' | $(FZF) --print-query | tail -1 ) \ && read -p "Article title? " name \ && filename="$$(echo "$$name" \ | 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" +.PHONY: all +all: $(default) ## All file targets + + %.md: [ -d "$(@D)" ] || mkdir $(@D) printf '%s\n' '---' >> $@ printf 'title: %s\n' '$(TITLE)' >> $@ - echo "tags: " >> $@ - echo $(@D) | sed 's#\/#\n- #g' >> $@ + printf "tags: " >> $@ + echo $(@D) | sed 's#\b\w#\n- &#g; s/\///g' >> $@ printf '%s\n\n' '---' >> $@ $(EDITOR) +5 $@ - git add $@ - git commit -m"article: $(TITLE)" diff --git a/README.md b/README.md index 85f0d70..a950b62 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,103 @@ ---- -title: Linux Knowledge Base ---- +# 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 -make -make database +lk(){ + /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 -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 +Add the function to your bash shell like this: -recsel db.rec -t guide -j provides -G title \ - -e "title = 'ssh'" \ - -p 'sum(provides_wordcount)' +```bash +make function +make function >> ~/.bashrc +exec bash +lk ``` # 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 -Articles should state what you need to understand in order to read them *at the start*. -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. +Articles should never link to other resources part-way through. +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. -Articles should not take a detour through a chain of other articles of unknown size. +## No History, No Context -[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 -- 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. ## 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. -## Show Arguments as Variables +## Show Options as Variables Look at this line: @@ -82,28 +124,51 @@ The answer is not obvious. It's better to make all arbitrary values variables. ```sh -git branch $branch_name -git checkout $branch_name +name=new +git branch ${name} +git checkout ${name} PAGER='less -R' grep ls --color=always $HISTFILE | $PAGER ``` 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. 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? +Why bother writing yet another cheat-sheet collection? + ## Man pages - Orders items by the alphabet rather than by relevance. - Often presumes you know everything except that one program. - Often written in the 80's, and it shows. - Zero respect for your time. -- Often references `info` pages (yuck). +- Sometimes reference `info` pages (yuck). ## `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 -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. - -Systemd is taken as a default. -Non-systemd commands are mentioned when required for a distro, e.g. runit for Void Linux. +If you like the format, send me a pull request. diff --git a/chat/profanity_automation.md b/chat/profanity_automation.md index 6f34490..6ed6804 100644 --- a/chat/profanity_automation.md +++ b/chat/profanity_automation.md @@ -4,7 +4,7 @@ tags: - chat - omemo requires: -- profanity +- chat/profanity.md --- Automate profanity with `--cmd`. diff --git a/chat/wgetpaste.md b/chat/wgetpaste.md index 7140137..e8822e6 100644 --- a/chat/wgetpaste.md +++ b/chat/wgetpaste.md @@ -28,3 +28,9 @@ Paste in the file then load the result to the right-hand clipboard: wgetpaste -s dpaste -X ``` +--- +title: +tags: +chat +--- + diff --git a/cmd.mk b/cmd.mk index ce2af77..d2e501b 100644 --- a/cmd.mk +++ b/cmd.mk @@ -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)) default += $(lists) -get_title = printf 'title: "%s"\n' '${1}' +get_title = printf 'title: %s\n' '${1}' get_tags = recsel -t $(basename $<) $< -G bin \ - -e 'bin = "$(1)"' -U -CP tag | \ + -e 'bin = "$(1)"' -U -CP tag,bin | \ sed 's/.*/- &/' list_commands = recsel -t $(basename $<) $< -e 'bin = "$(1)"' | \ recfmt -f lists.fmt -lists/%.md: command.rec | lists/ +$(lists): lists/%.md: command.rec | lists/ @printf '%s\n' '---' > $@ @$(call get_title,$(basename $(notdir $@))) >> $@ @printf '%s\n' 'tags: ' >> $@ @@ -22,3 +22,20 @@ lists/%.md: command.rec | lists/ .PHONY: cmd 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} + diff --git a/command.rec b/command.rec index 1428eae..75d5b7d 100644 --- a/command.rec +++ b/command.rec @@ -1,14 +1,11 @@ %rec: command %doc: shell command examples %type: aim line -%allowed: aim -+ cmd bin -+ tag -+ shell +%allowed: aim cmd bin tag note shell %unique: shell -aim: Put output into column -cmd: du -h /etc/* | column +aim: Put output into columns +cmd: ip a | grep inet | column -ts' ' shell: sh bin: column tag: format @@ -19,14 +16,16 @@ shell: sh bin: column 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 +note: Hide some columns with `-H`. shell: sh bin: column 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 +note: Unspecified items remain. shell: sh bin: column tag: format @@ -38,48 +37,55 @@ bin: column tag: format tag: json -aim: Make a QR Code image: -cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "$FILE".png +aim: Make a QR Code image +cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "${file}".png shell: sh bin: qrencode 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" shell: sh bin: qrencode tag: qr -aim: Read a QR Code image: -cmd: zbarimg $FILE +aim: Read a QR Code image +cmd: zbarimg ${file} shell: sh bin: qrencode 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 shell: sh bin: qrencode +bin: nmcli tag: qr 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 shell: sh bin: sed tag: recfiles 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 + 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 bin: sed bin: recinf tag: recfiles 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://${user}@${server}:${port}//${path}/${file} shell: sh @@ -87,19 +93,363 @@ bin: vim bin: scp 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 cmd: sudo ntpd -q -g -x -n bin: ntpd 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 -cmd: mlr --imarkdown --ocsv cat ''.md +cmd: mlr --imarkdown --ocsv cat ${file}.md bin: mlr tag: csv tag: markdown tag: data aim: Convert a csv file to markdown -cmd: mlr --icsv --omd cat ''.csv +cmd: mlr --icsv --omd cat ${file}.csv 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 diff --git a/data/git/cleanup.md b/data/git/cleanup.md index 0252a5e..d5c7748 100644 --- a/data/git/cleanup.md +++ b/data/git/cleanup.md @@ -4,7 +4,7 @@ tags: - data - setup requires: -- git +- data/git.md --- diff --git a/data/git/commit_for_another.md b/data/git/commit_for_another.md index 819d9c2..ac31af8 100644 --- a/data/git/commit_for_another.md +++ b/data/git/commit_for_another.md @@ -4,7 +4,7 @@ tags: - data - git requires: -- git +- data/git.md --- You can make Alice the author, while you are still the commiter: diff --git a/data/git/git-lfs.md b/data/git/git-lfs.md index 43a040b..d6a43ea 100644 --- a/data/git/git-lfs.md +++ b/data/git/git-lfs.md @@ -4,7 +4,7 @@ tags: - data - git requires: -- git +- data/git.md --- Git Large File Storage ('LFS') needs to change your `~/.gitconfig` to check out those binary files: diff --git a/data/git/git_stash.md b/data/git/git_stash.md index e028f77..b5637db 100644 --- a/data/git/git_stash.md +++ b/data/git/git_stash.md @@ -4,7 +4,7 @@ tags: - data - git requires: -- git +- data/git.md --- Save file-changes without committing anything. diff --git a/data/gpg/gpg_pinentry.md b/data/gpg/gpg_pinentry.md index 1a45bed..4d4f834 100644 --- a/data/gpg/gpg_pinentry.md +++ b/data/gpg/gpg_pinentry.md @@ -5,8 +5,8 @@ tags: - secrets - TUI requires: -- gpg -- vim +- data/gpg.md +- writing/vim.md --- diff --git a/data/gpg/vim_decryption.md b/data/gpg/vim_decryption.md index dae97ce..4dd9a0f 100644 --- a/data/gpg/vim_decryption.md +++ b/data/gpg/vim_decryption.md @@ -4,10 +4,10 @@ tags: - vim - data - gpg -requires: -- gpg -- vim - comfy +requires: +- data/gpg.md +- writing/vim.md --- The `vim-gnupg` plug-in lets vim edit gpg-encrypted files as if they were unencrypted. diff --git a/data/groff.md b/data/groff.md index cbfce14..507edce 100644 --- a/data/groff.md +++ b/data/groff.md @@ -1,7 +1,8 @@ --- title: groff tags: -- data +- documentation +- typography - logic --- # Basic Documents @@ -62,8 +63,6 @@ The equation shorthands are predictable: | Not equal | != | | Superscript | sup {thing} | -- [List of symbols](https://www.math-linux.com/man/man7/groff_char.7.html) - ### Examples The fraction 2/5ths: diff --git a/data/newsboat.md b/data/newsboat.md index d97c017..31c9771 100644 --- a/data/newsboat.md +++ b/data/newsboat.md @@ -13,7 +13,7 @@ mkdir ~/.config/newsboat 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. diff --git a/data/pass.md b/data/pass.md index bdefb5a..a1adf91 100644 --- a/data/pass.md +++ b/data/pass.md @@ -5,7 +5,7 @@ tags: - credentials - secrets requires: -- gpg +- data/gpg.md --- Setup [gpg](gpg.md) keys. diff --git a/data/pass_otp.md b/data/pass_otp.md index 0a9988f..dfc80c2 100644 --- a/data/pass_otp.md +++ b/data/pass_otp.md @@ -7,7 +7,7 @@ tags: - 2fa - otp requires: -- pass +- data/pass.md --- Need a Microsoft or Google authenticator? diff --git a/data/pdf-to-txt.sh b/data/pdf-to-txt.sh deleted file mode 100755 index c6da2a9..0000000 --- a/data/pdf-to-txt.sh +++ /dev/null @@ -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 diff --git a/data/pdf_erasure.md b/data/pdf_erasure.md index 7af95f4..a622422 100644 --- a/data/pdf_erasure.md +++ b/data/pdf_erasure.md @@ -4,7 +4,7 @@ tags: - metadata - ghost script - gs -- .pdf +- pdf --- You cannot erase pdf metadata with `exiftool` (it only *appends* your changes). diff --git a/data/radicale.md b/data/radicale.md index 3abf850..cce2319 100644 --- a/data/radicale.md +++ b/data/radicale.md @@ -4,8 +4,7 @@ tags: - data - calendar requires: -- nginx -- certbot +- networking/nginx.md --- Check before you start: diff --git a/data/recfiles/bibliography.md b/data/recfiles/bibliography.md index c2caa0d..5d8aabb 100644 --- a/data/recfiles/bibliography.md +++ b/data/recfiles/bibliography.md @@ -6,9 +6,9 @@ tags: - recfiles - tex requires: -- recfiles -- tex -- makefiles +- data/recfiles.md +- writing/tex.md +- system/makefiles.md --- Store your bibliography in a `recfile` database, then extract any part with `make`. diff --git a/data/recfiles/board_games.md b/data/recfiles/board_games.md index 077c269..ceaa02f 100644 --- a/data/recfiles/board_games.md +++ b/data/recfiles/board_games.md @@ -5,7 +5,7 @@ tags: - recfiles - games requires: -- recfiles +- data/recfiles.md --- You can play with a board games database from boardgamegeek.com. diff --git a/data/recfiles/extended.md b/data/recfiles/extended.md index 1b56d31..d80cfe3 100644 --- a/data/recfiles/extended.md +++ b/data/recfiles/extended.md @@ -5,7 +5,7 @@ tags: - database - recfiles requires: -- recfiles +- data/recfiles.md --- ## Create diff --git a/data/recfiles/ip_asn.md b/data/recfiles/ip_asn.md index 63a8945..5c10d3d 100644 --- a/data/recfiles/ip_asn.md +++ b/data/recfiles/ip_asn.md @@ -4,7 +4,8 @@ tags: - data - recfiles - games -requires: recfiles +requires: +- data/recfiles.md --- ## Download the Database diff --git a/data/recfiles/nginx_logs.md b/data/recfiles/nginx_logs.md index 016a023..e31a00c 100644 --- a/data/recfiles/nginx_logs.md +++ b/data/recfiles/nginx_logs.md @@ -5,8 +5,8 @@ tags: - recfiles - logs requires: -- recfiles -- nginx +- data/recfiles.md +- 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: diff --git a/data/recfiles/recfixes.md b/data/recfiles/recfixes.md index 577693d..c8a50e3 100644 --- a/data/recfiles/recfixes.md +++ b/data/recfiles/recfixes.md @@ -4,7 +4,7 @@ tags: - data - recfiles requires: -- recfiles +- data/recfiles.md --- Sometimes `recsel` chokes on a large query, and you need to break the query into chunks with a pipe. diff --git a/data/sc-im.md b/data/sc-im.md index 2dcc876..c3090a5 100644 --- a/data/sc-im.md +++ b/data/sc-im.md @@ -6,7 +6,7 @@ tags: - spreadsheet - csv requires: -- vim +- writing/vim.md --- - [Sample file](sc-im/sample.sc) diff --git a/data/search_system.md b/data/search_system.md index 9c4a04f..9a1be85 100644 --- a/data/search_system.md +++ b/data/search_system.md @@ -5,7 +5,8 @@ tags: - search - locate - plocate -requires: cron +requires: +- system/cron.md --- You can search every file on the computer instantly by installing `plocate`. diff --git a/data/soft-serve.md b/data/soft-serve.md index df0e5a8..b4c9bd2 100644 --- a/data/soft-serve.md +++ b/data/soft-serve.md @@ -6,8 +6,8 @@ tags: - lfs - TUI requires: -- git -- nginx +- data/git.md +- networking/nginx.md --- - [Soft-Serve with https](soft-serve/soft_https.md) diff --git a/data/soft-serve/soft_https.md b/data/soft-serve/soft_https.md index fea8a55..8cd9f8d 100644 --- a/data/soft-serve/soft_https.md +++ b/data/soft-serve/soft_https.md @@ -5,8 +5,8 @@ tags: - git server - lfs requires: -- git -- nginx +- data/git.md +- networking/nginx.md --- ## `http` Setup diff --git a/data/soft-serve/soft_maintenance.md b/data/soft-serve/soft_maintenance.md index 6eb6b62..526fc24 100644 --- a/data/soft-serve/soft_maintenance.md +++ b/data/soft-serve/soft_maintenance.md @@ -5,8 +5,8 @@ tags: - git server - maintenance requires: -- git -- nginx +- data/git.md +- networking/nginx.md --- Over time git repositories become bloated with old data, but never get cleaned. diff --git a/data/unison.md b/data/unison.md index 99e193d..71d6201 100644 --- a/data/unison.md +++ b/data/unison.md @@ -4,7 +4,7 @@ tags: - backups - synch 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). diff --git a/distros/arch/basic-install.md b/distros/arch/basic_install.md similarity index 98% rename from distros/arch/basic-install.md rename to distros/arch/basic_install.md index a1fdd6c..fe76d55 100644 --- a/distros/arch/basic-install.md +++ b/distros/arch/basic_install.md @@ -3,7 +3,7 @@ title: Install Arch tags: - arch requires: -- partitions +- system/partitions.md --- Keyboard layout changed. diff --git a/distros/arch/install_yay.md b/distros/arch/install_yay.md index f3e1f3e..959495f 100644 --- a/distros/arch/install_yay.md +++ b/distros/arch/install_yay.md @@ -3,7 +3,8 @@ title: Install yay tags: - distros - arch -requirements: [ "pacman" ] +requires: +- distros/arch/basic_install.md --- ```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. ```sh -yay +yay ${search_term} ``` 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. -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 -yay -S --noconfirm --sudoloop +yay -S --noconfirm --sudoloop ${package_name} ``` diff --git a/distros/arch/maintenance.md b/distros/arch/maintenance.md index 313c932..2baa1cd 100644 --- a/distros/arch/maintenance.md +++ b/distros/arch/maintenance.md @@ -2,7 +2,9 @@ title: Arch Maintenance tags: - arch -requirements: [ "pacman" ] +requires: +- pacman +- vim --- # Package Cache diff --git a/distros/arch/pacman.md b/distros/arch/pacman.md index 2b975b8..6cb0859 100644 --- a/distros/arch/pacman.md +++ b/distros/arch/pacman.md @@ -2,7 +2,8 @@ title: pacman tags: - distros -requirements: [ "Install Arch" ] +requires: +- distros/arch/basic_install.md --- Packages are kept in /var/cache/pacman/pkg. diff --git a/distros/arch/pacman_extras.md b/distros/arch/pacman_extras.md index 00c6f7e..9020d1c 100644 --- a/distros/arch/pacman_extras.md +++ b/distros/arch/pacman_extras.md @@ -2,7 +2,8 @@ title: pacman - Extras tags: - distros -requirements: [ "pacman" ] +requires: +- distros/arch/pacman.md --- ## Unattended Actions @@ -24,7 +25,7 @@ You can tell `pacman` that this is a dependency for another package: ```sh -pacman -S --noconfirm --asdeps +pacman -S --noconfirm --asdeps ${weird_music_player} ``` When you [remove orphaned packages](pacman.md), the package will be automatically uninstalled. diff --git a/distros/arch/yay_maintenance.md b/distros/arch/yay_maintenance.md index 5ecd142..b920730 100644 --- a/distros/arch/yay_maintenance.md +++ b/distros/arch/yay_maintenance.md @@ -1,13 +1,15 @@ --- -title: Arch Maintenance with yay +title: Arch maintenance with yay tags: - arch -requirements: [ "Arch Maintenance" ] +- maintenance +requires: +- distros/arch/maintenance.md --- # Package Cache -Just like `pacman` +Just like `[pacman](distros/arch/pacman.md)` with a couple of extras. ```sh ls ~/.cache/yay/ | wc -l diff --git a/distros/void/autologin.md b/distros/void/autologin.md index 9a0f933..4531070 100644 --- a/distros/void/autologin.md +++ b/distros/void/autologin.md @@ -2,34 +2,53 @@ title: Void Autologin tags: - 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 -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 +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 - # util-linux specific settings - if [ "${tty}" = "tty1" ]; then - GETTY_ARGS="--noclear" - fi + # util-linux specific settings + if [ "${tty}" = "tty1" ]; then + GETTY_ARGS="--autologin ${your_username} --noclear" + 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 -# autologin on tty1 - if [ -z "$DISPLAY" ] && [ "$(fgconsole)" -eq 1 ]; then - exec startx - fi - +sudo touch /etc/sv/agetty-tty1/down ``` + +Enable your `${login}` service: + + +```sh +sudo ln -s /etc/sv/${login} /var/service/ +``` + +Reboot. + +Pizza party for one. diff --git a/example.rec b/example.rec index ac9822f..65884c6 100644 --- a/example.rec +++ b/example.rec @@ -1,7 +1,39 @@ %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 bin: sc-im +usage: {{bin}} {{filename}} note: Basic sc-im example of adding and averaging content: # This data file was generated by the Spreadsheet Calculator Improvised (sc-im) + # 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 4 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 ' Something about CSS probably ' > $@ ++ echo '' >> $@ ++ ++ html/foot.html: html/head.html ++ echo '' >> $@ ++ ++ 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 diff --git a/lists.fmt b/lists.fmt index 6bb67b5..6212462 100644 --- a/lists.fmt +++ b/lists.fmt @@ -4,3 +4,5 @@ ```{{shell}} {{cmd}} ``` + +{{note}} diff --git a/networking/agate.md b/networking/agate.md index e26c8fe..da2c90c 100644 --- a/networking/agate.md +++ b/networking/agate.md @@ -4,6 +4,8 @@ tags: - networking - arch - gemini +requires: +- distros/arch/install_yay.md --- 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: -`SVFILE=st` +`${svfile}=st` ``` echo " @@ -63,27 +65,27 @@ CERT=--certs $GEMDIR/.certs ADDR=--addr [::]:1965 --addr 0.0.0.0:1965 HOSTNAME=--hostname $DOMAIN1 --hostname $DOMAIN2 LANG=--lang $LANG -" > $SVFILE.conf +" > ${svfile}.conf ``` 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: -`mv $SVFILE.conf /etc/agate/` +`mv ${svfile}.conf /etc/agate/` And finally, start the service: ``` 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: ``` -journalctl -xeu agate@$SVFILE.conf +journalctl -xeu agate@${svfile}.conf ``` diff --git a/networking/dns.md b/networking/dns.md index 1924370..46b1cda 100644 --- a/networking/dns.md +++ b/networking/dns.md @@ -1,5 +1,5 @@ --- -title: dns +title: DNS Record List tags: - networking - host @@ -12,10 +12,9 @@ tags: | CNAME | Alternative Address | "$domain".rs, "$subdomain.$domain".com | | NS | Nameserver | ns1.fastname.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 host $domain.$tld diff --git a/networking/fail2ban.md b/networking/fail2ban.md index 7d15e44..e74d8c9 100644 --- a/networking/fail2ban.md +++ b/networking/fail2ban.md @@ -3,7 +3,7 @@ title: fail2ban tags: - networking requires: -- ssh +- networking/ssh.md --- # SSH Daemon Jail diff --git a/networking/nat_check.md b/networking/nat_check.md new file mode 100644 index 0000000..1020ed4 --- /dev/null +++ b/networking/nat_check.md @@ -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 diff --git a/networking/nmap.md b/networking/nmap.md index 7305dc2..3132906 100644 --- a/networking/nmap.md +++ b/networking/nmap.md @@ -12,9 +12,9 @@ nmap 192.168.1.1/24 Flags: -| Flag | Meaning | Effect | -| :---| :---| :---| -| -F | Fast | First 100 ports only | +| Flag | Meaning | Effect | +|:-----|:--------|:---------------------| +| -F | Fast | First 100 ports only | Look for a web server, which has ports 80 and 443 open: diff --git a/networking/ssh/sshfs.md b/networking/ssh/sshfs.md index 54692d3..027a61e 100644 --- a/networking/ssh/sshfs.md +++ b/networking/ssh/sshfs.md @@ -3,7 +3,7 @@ title: sshfs tags: - networking requires: -- ssh +- networking/ssh.md --- # Mount diff --git a/networking/ssh/tricks.md b/networking/ssh/tricks.md index c2a4979..da06dba 100644 --- a/networking/ssh/tricks.md +++ b/networking/ssh/tricks.md @@ -5,7 +5,7 @@ tags: - ssh - tricks requires: -- ssh +- networking/ssh.md --- Mount a remote filesystem locally with fuse-sshfs: diff --git a/required.fmt b/required.fmt new file mode 100644 index 0000000..f508f2b --- /dev/null +++ b/required.fmt @@ -0,0 +1 @@ +- ({{requires_title}})[{{requires}}] diff --git a/shell/options.md b/shell/options.md new file mode 100644 index 0000000..bc7fe3d --- /dev/null +++ b/shell/options.md @@ -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. diff --git a/shell/readline.md b/shell/readline.md index 6f4fe5f..b38c00f 100644 --- a/shell/readline.md +++ b/shell/readline.md @@ -2,9 +2,10 @@ title: Use the terminal in vi-mode tags: - shell -- vi +- vim - comfy - readline +- python --- # Vi-Commands diff --git a/shell/scripts.md b/shell/scripts.md new file mode 100644 index 0000000..d6cd26e --- /dev/null +++ b/shell/scripts.md @@ -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. diff --git a/sound/mpd_pipewire.md b/sound/mpd_pipewire.md index 29c2378..da15ec8 100644 --- a/sound/mpd_pipewire.md +++ b/sound/mpd_pipewire.md @@ -3,7 +3,8 @@ title: mpd with pipewire tags: - sound - pipewire -requirements: [ "pipewire" ] +requires: +- sound/pipewire.md --- # Setup diff --git a/system/ansible.md b/system/ansible.md index f65b68d..8653129 100644 --- a/system/ansible.md +++ b/system/ansible.md @@ -5,8 +5,8 @@ tags: - ansible - orchestration requires: -- ssh -- pass +- networking/ssh.md +- data/pass.md --- # Start Locally diff --git a/system/ansible/ansible_with_docker.md b/system/ansible/ansible_with_docker.md index 15b57d4..e74577b 100644 --- a/system/ansible/ansible_with_docker.md +++ b/system/ansible/ansible_with_docker.md @@ -5,8 +5,8 @@ tags: - ansible - docker requires: -- docker -- ansible +- virtualization/docker.md +- system/ansible.md --- 'Docker module', you say? diff --git a/system/awk.md b/system/awk.md index 7f3ef52..a050797 100644 --- a/system/awk.md +++ b/system/awk.md @@ -2,7 +2,7 @@ title: awk tags: - system -- .csv +- csv --- # Basics diff --git a/system/groups.md b/system/groups.md index 242f072..51947ab 100644 --- a/system/groups.md +++ b/system/groups.md @@ -7,33 +7,46 @@ tags: Check which groups you are in, and which are available: ```sh -cat /etc/group 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 -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 -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 -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`: ```sh groups -sudo su $USER +grep audio /etc/group + +sudo usermod -aG audio $USER groups +grep audio /etc/group + +su $USER +groups +grep audio /etc/group ``` + diff --git a/system/makefiles/python_projects.md b/system/makefiles/python_projects.md index 9fa6cf5..cdfa34a 100644 --- a/system/makefiles/python_projects.md +++ b/system/makefiles/python_projects.md @@ -1,13 +1,13 @@ --- title: Python Projects with Makefiles tags: -- tutorial +- setup - system - makefiles - graphviz - python 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`. diff --git a/system/systemd.md b/system/systemd.md deleted file mode 100644 index 182d008..0000000 --- a/system/systemd.md +++ /dev/null @@ -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 -``` - diff --git a/system/systemd/journal.md b/system/systemd/journal.md deleted file mode 100644 index 6243d27..0000000 --- a/system/systemd/journal.md +++ /dev/null @@ -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 -``` - diff --git a/system/systemd/making-services.md b/system/systemd/making-services.md index 338ed05..eb79bcf 100644 --- a/system/systemd/making-services.md +++ b/system/systemd/making-services.md @@ -1,13 +1,23 @@ ---- +- title: Making Services tags: - 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 @@ -21,18 +31,10 @@ ExecStart=/path/to/script [Install] WantedBy=multi-user.target - - ``` -After making the new service, systemd requires reloading: +## Types -```sh -sudo systemctl daemon-reload -``` - -# Types - -* simple - the service cannot be called on by others. It runs on repeat. -* oneshot - the service executes once, then stops. +* `simple` - the service runs forever. Other services do not stop it. +* `oneshot` - the service executes once, then stops. diff --git a/system/systemd/test.service b/system/systemd/test.service deleted file mode 100644 index 593948e..0000000 --- a/system/systemd/test.service +++ /dev/null @@ -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 - - diff --git a/virtualization/docker.md b/virtualization/docker.md index df9e635..57994c3 100644 --- a/virtualization/docker.md +++ b/virtualization/docker.md @@ -4,8 +4,9 @@ tags: - documentation - virtualization requires: -- groups +- system/groups.md --- + ```sh 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. ```sh -# docker info +docker info | less -Ri ``` This should show you things are working. diff --git a/virtualization/kubernetes/kubernetes_basics.md b/virtualization/kubernetes/kubernetes_basics.md index cce108b..820a17d 100644 --- a/virtualization/kubernetes/kubernetes_basics.md +++ b/virtualization/kubernetes/kubernetes_basics.md @@ -4,7 +4,7 @@ tags: - virtualization - kubernetes requires: -- minikube_setup +- virtualization/kubernetes/minikube_setup.md --- Install `kubectl`. diff --git a/virtualization/kubernetes/kubernetes_explain.md b/virtualization/kubernetes/kubernetes_explain.md index ec956bc..920a5ee 100644 --- a/virtualization/kubernetes/kubernetes_explain.md +++ b/virtualization/kubernetes/kubernetes_explain.md @@ -3,11 +3,11 @@ title: Kubernetes Docs tags: - virtualization - kubernetes -- WTFM +- wtfm - hosts -- DNS +- dns requires: -- minikube_setup +- virtualization/kubernetes/minikube_setup.md --- `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. ```sh -t="$(kubectl api-resources | fzy | gawk '{print $1}')" +t="$(kubectl api-resources | fzf | gawk '{print $1}')" kubectl explain ${t} ``` diff --git a/virtualization/kubernetes/minikube_setup.md b/virtualization/kubernetes/minikube_setup.md index addd5d3..e7119e0 100644 --- a/virtualization/kubernetes/minikube_setup.md +++ b/virtualization/kubernetes/minikube_setup.md @@ -4,10 +4,12 @@ tags: - virtualization - kubernetes - minikube -- docker +requires: +- virtualization/docker.md --- # Install `minikube` + Set up a practice environment with `minikube`, using either Docker or VirtualBox. 1. Install the driver (VirtualBox is a good choice). diff --git a/virtualization/kubernetes/proxy_api.md b/virtualization/kubernetes/proxy_api.md index 72f3318..3693e1d 100644 --- a/virtualization/kubernetes/proxy_api.md +++ b/virtualization/kubernetes/proxy_api.md @@ -4,7 +4,7 @@ tags: - virtualization - kubernetes requires: -- minikube_setup +- virtualization/kubernetes/minikube_setup.md --- Start the proxy: diff --git a/virtualization/virtualbox.md b/virtualization/virtualbox.md index 4add36e..d551d66 100644 --- a/virtualization/virtualbox.md +++ b/virtualization/virtualbox.md @@ -3,7 +3,7 @@ title: virtualbox tags: - system requires: -- groups +- system/groups.md --- # Setup diff --git a/vision/ffmpeg.md b/vision/ffmpeg.md deleted file mode 100644 index 9fa5683..0000000 --- a/vision/ffmpeg.md +++ /dev/null @@ -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 -``` - diff --git a/vision/imagemagick.md b/vision/imagemagick.md deleted file mode 100644 index cab9dde..0000000 --- a/vision/imagemagick.md +++ /dev/null @@ -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 \( +clone -background black -shadow 50x8+0+5 \) +swap -background none -layers merge +repage ` -``` - - -# 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 -``` - diff --git a/vision/lowdown.md b/vision/lowdown.md index 59c9242..094796e 100644 --- a/vision/lowdown.md +++ b/vision/lowdown.md @@ -2,7 +2,7 @@ title: Markdown to PDF tags: - markdown -- .pdf +- pdf - vision --- diff --git a/vision/lowdown/example.txt b/vision/lowdown/example.txt deleted file mode 100644 index a9d00e2..0000000 --- a/vision/lowdown/example.txt +++ /dev/null @@ -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 ' Something about CSS probably ' > $@ - echo '' >> $@ - -html/foot.html: html/head.html - echo '' >> $@ - -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 diff --git a/writing/tex/calendar.md b/writing/tex/calendar.md index 7e181bd..2020b0a 100644 --- a/writing/tex/calendar.md +++ b/writing/tex/calendar.md @@ -1,11 +1,11 @@ --- -title: Calendar +title: Output a LaTeX Calendar tags: - writing - tex - fun requires: -- tex_packages +- writing/tex/tex_packages.md --- ```sh diff --git a/writing/vim/completion.md b/writing/vim/completion.md index e3a9ae9..00facab 100644 --- a/writing/vim/completion.md +++ b/writing/vim/completion.md @@ -5,7 +5,7 @@ tags: - completion - TUI requires: -- vim +- writing/vim.md --- Complete the word by searching for the *n*ext similar word: diff --git a/writing/vim/linewrap.md b/writing/vim/linewrap.md index 21ac09f..5225a34 100644 --- a/writing/vim/linewrap.md +++ b/writing/vim/linewrap.md @@ -6,7 +6,7 @@ tags: - linewrap - TUI requires: -- vim +- writing/vim.md --- Wrap lines in a file to 80 characters with `gqG`. diff --git a/writing/vim/navigate.md b/writing/vim/navigate.md index d962122..1984713 100644 --- a/writing/vim/navigate.md +++ b/writing/vim/navigate.md @@ -5,7 +5,7 @@ tags: - navigation - TUI requires: -- vim +- writing/vim.md --- | Move | Command | diff --git a/writing/vim/subs.md b/writing/vim/subs.md index 6d5e827..2c04e1a 100644 --- a/writing/vim/subs.md +++ b/writing/vim/subs.md @@ -7,7 +7,7 @@ tags: - find - TUI requires: -- vim +- writing/vim.md --- Search for the next and or previous occurrence of the word under your cursor with `*` and `#`. diff --git a/writing/vim/vi.md b/writing/vim/vi.md index 3c94c35..b49ddee 100644 --- a/writing/vim/vi.md +++ b/writing/vim/vi.md @@ -5,7 +5,7 @@ tags: - learning - TUI requires: -- vim +- writing/vim.md --- 1. Uninstall `vim`. diff --git a/writing/vim/vim_in_bash.md b/writing/vim/vim_in_bash.md index d769b2f..98e7f10 100644 --- a/writing/vim/vim_in_bash.md +++ b/writing/vim/vim_in_bash.md @@ -6,7 +6,7 @@ tags: - inputrc - TUI requires: -- vim +- writing/vim.md --- Put bash in vim mode! diff --git a/writing/vim/windows.md b/writing/vim/windows.md index 72d1953..f094678 100644 --- a/writing/vim/windows.md +++ b/writing/vim/windows.md @@ -4,7 +4,7 @@ tags: - vim - TUI requires: -- vim +- writing/vim.md --- | Command | Keys |