Compare commits
17 Commits
59fb0ada24
...
7e75763cee
Author | SHA1 | Date | |
---|---|---|---|
7e75763cee | |||
2d3961e0f5 | |||
72ad0786c8 | |||
b64d9de0c4 | |||
fa9c8edb1d | |||
741e988536 | |||
a72e2b117d | |||
cc574d5358 | |||
0d76eb0531 | |||
3bfeacd2d7 | |||
ed4b54cf7e | |||
4e89c5ab9b | |||
1732c62734 | |||
fb157895fb | |||
b3258d9f5f | |||
d793bca3ea | |||
14470b6f92 |
31
Makefile
31
Makefile
@ -24,35 +24,36 @@ $(foreach dir, $(categories), \
|
||||
$(eval .dbs/$(dir).rec: $(wildcard $(dir)/*)) \
|
||||
)
|
||||
|
||||
$(databases): .dbs/%.rec: %/
|
||||
.dbs/:
|
||||
mkdir $@
|
||||
$(databases): .dbs/%.rec: %/ | .dbs/
|
||||
$(info making $(@F))
|
||||
@mkdir -p $(@D)
|
||||
for entry in $(shell find $< -type f -name "*.md") ; do \
|
||||
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
|
||||
sed -e 's/\[ //' -e 's/ \]//' |\
|
||||
tr -d '"' ;\
|
||||
printf "wordcount: %s\n" "$$(wc -w < $$entry)" ;\
|
||||
printf "file: %s\n\n" "$$entry" ;\
|
||||
printf "file: %s\n" "$$entry" ;\
|
||||
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
|
||||
tr -d '[]' | tr -s ' ' |\
|
||||
sed '/tags: /s/, /\ntag: /g ; s/tags:/tag:/ ; /requires/s/, /\nrequires: /g' ;\
|
||||
printf "wordcount: %s\n\n" "$$(wc -w < $$entry)" ;\
|
||||
done > $@
|
||||
for entry in $(shell find $< -type f -name "*.md"); do \
|
||||
recset $@ -e "file = '$${entry}'" -f wordcount --set-add="$$(wc -w < $${entry})" ;\
|
||||
recset $@ -e "file = '$${entry}'" -f content --set-add="$$($(spill_contents) $${entry})" ;\
|
||||
done
|
||||
|
||||
# This two-variable read can only happen because of the quotes in the titles.
|
||||
db.rec: $(databases)
|
||||
printf '%s\n' '%rec: guide' > $@
|
||||
printf '%s\n' '%key: title' >> $@
|
||||
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: title' >> $@
|
||||
recsel $^ >> $@
|
||||
printf '%s\n\n' '%sort: wordcount' >> $@
|
||||
cat $^ >> $@
|
||||
recsel $@ -e "requires != ''" -CR title,requires |\
|
||||
while read title requires; do \
|
||||
IFS=', ' && for provider in $$requires; do \
|
||||
for provider in "$$requires" ; do \
|
||||
recset $@ -e "title = '$${provider}'" -f provides -a "$${title}" ;\
|
||||
done ;\
|
||||
done
|
||||
$(info Created main database: $@)
|
||||
sed -i 's/"//g' $@
|
||||
recfix --sort $@
|
||||
$(info Created main database: $@)
|
||||
|
||||
default += db.rec
|
||||
|
||||
|
23
README.md
23
README.md
@ -4,23 +4,29 @@ title: "Linux Knowledge Base"
|
||||
|
||||
The Linux Knowledge-Base provides quick-start guides for working with terminal programs.
|
||||
|
||||
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.
|
||||
|
||||
# Setup
|
||||
|
||||
Install `make`, `recutils`, and any fuzzy-finder (i.e. `sk`, `fzy`, or `fzf`).
|
||||
|
||||
## Usage
|
||||
|
||||
Set up the database and try a few queries:
|
||||
|
||||
```sh
|
||||
make
|
||||
make database
|
||||
|
||||
recsel db.rec -m 3
|
||||
recsel db.rec -q database
|
||||
recsel db.rec -q gpg
|
||||
recsel db.rec -e "title = 'ssh'"
|
||||
recsel db.rec -e "title ~ 'ssh'"
|
||||
recsel db.rec -e "title ~ 'bash'" -R title,wordcount
|
||||
recsel db.rec -m 1 -P content | less -R
|
||||
|
||||
recsel db.rec -t guide -j provides -G title \
|
||||
-e "title = 'ssh'" \
|
||||
-p 'sum(provides_wordcount)'
|
||||
```
|
||||
|
||||
# Style
|
||||
@ -30,6 +36,14 @@ recsel db.rec -m 1 -P content | less -R
|
||||
- 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.
|
||||
|
||||
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.
|
||||
|
||||
## Be Opinionated
|
||||
|
||||
- Guides should not ask the reader to select options half-way through.
|
||||
@ -74,6 +88,11 @@ grep ls --color=always $HISTFILE | $PAGER
|
||||
|
||||
Now we can see what can be changed.
|
||||
|
||||
## Assume People Follow the Instructions
|
||||
|
||||
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.
|
||||
|
||||
# What's Wrong with Everything Else?
|
||||
|
||||
## Man pages
|
||||
|
@ -8,22 +8,21 @@ tags: [ "tar", "backups", ".tgz", "tar.gz" ]
|
||||
|
||||
Combine many files and directories into a single t-archive file.
|
||||
|
||||
```bash
|
||||
```sh
|
||||
tar cf "$ARCHIVE".tar $DIR
|
||||
```
|
||||
You can remember this with the mnemonic '*C*reate *F*ile'.
|
||||
|
||||
Unfortunately, this stores the full file path, so making a tar archive of `/etc/nginx/` will store `etc/nginx` (without the leading `/`.
|
||||
|
||||
Unfortunately, this stores the full file path, so making a tar archive of `/etc/nginx/` will store `etc/nginx` (without the leading `/`).
|
||||
It's often better to tell tar which path to start from using the `-C` flag.
|
||||
|
||||
```bash
|
||||
```sh
|
||||
tar cf "$ARCHIVE".tar -C /etc/ nginx
|
||||
```
|
||||
|
||||
Check the contents of your archive with:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
tar tf "$ARCHIVE".tar
|
||||
```
|
||||
|
||||
@ -31,7 +30,7 @@ If you want to store 'everything in a directory', then using `*` will not work,
|
||||
|
||||
Instead, you can store the target in a variable:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
files=$(ls /etc/nginx)
|
||||
tar cf "$ARCHIVE".tar -C /etc/nginx/ $file
|
||||
```
|
||||
@ -40,7 +39,9 @@ tar cf "$ARCHIVE".tar -C /etc/nginx/ $file
|
||||
|
||||
Extract the tar archive with
|
||||
|
||||
> tar xf "$ARCHIVE".tar
|
||||
```sh
|
||||
tar xf "$ARCHIVE".tar
|
||||
```
|
||||
|
||||
You can remember this with the mnemonic 'e*X*tract *F*ile'.
|
||||
|
||||
@ -48,7 +49,7 @@ You can remember this with the mnemonic 'e*X*tract *F*ile'.
|
||||
|
||||
Create a zip-compressed archive with the `z` flag.
|
||||
|
||||
```bash
|
||||
```sh
|
||||
tar czf "$ARCHIVE".tgz -C /etc/nginx/ $file
|
||||
```
|
||||
|
||||
@ -60,18 +61,16 @@ You can use any file ending you want, but sane people like to use '.tgz' or '.ta
|
||||
|
||||
Make archive:
|
||||
|
||||
```bash
|
||||
PASSWORD=my_password
|
||||
```
|
||||
```bash
|
||||
7za a -tzip -p$PASSWORD -mem=AES256 $ARCHIVE.zip $FILE_1 $FILE_2
|
||||
```sh
|
||||
7za a -tzip -p "$PASSWORD" -mem=AES256 $ARCHIVE.zip $FILE_1 $FILE_2
|
||||
```
|
||||
|
||||
Note that people can still see every filename in your archive, and can change those files.
|
||||
They just can't read the contents.
|
||||
|
||||
Unzip:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
7za x archive.zip
|
||||
```
|
||||
|
||||
|
@ -5,7 +5,7 @@ tags: [ "backups", "synch" ]
|
||||
|
||||
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).
|
||||
|
||||
```bash
|
||||
```sh
|
||||
unison -version
|
||||
```
|
||||
|
||||
@ -13,14 +13,14 @@ Create the `~/.unison` directory on both machines.
|
||||
|
||||
Make a job called `backup`:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
JOB=backup
|
||||
```
|
||||
|
||||
Here is an example job, which synchronizes the `~/music` directory with a remote machine which has the same username.
|
||||
|
||||
|
||||
```bash
|
||||
```sh
|
||||
echo "
|
||||
auto = true
|
||||
root=$HOME
|
||||
@ -42,7 +42,7 @@ The last command means it will ignore any file with a name ending in `.flac`.
|
||||
The first command means this will run but also confirm which files will be deleted, and which will be transferred, us `batch = true` instead.
|
||||
Or you can deleted that line in the `.prf` file and run it with a flag:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
unison -batch *backup*.prf
|
||||
```
|
||||
|
||||
|
@ -3,6 +3,24 @@ title: "Base 16"
|
||||
tags: [ "data" ]
|
||||
---
|
||||
|
||||
```bash
|
||||
Base 16 numbers often use `0x` at the start, so '10' just means '10', but `0x10` means '10 in base 16' which means '16'.
|
||||
|
||||
For small numbers, use `printf`.
|
||||
|
||||
```sh
|
||||
printf "%x" $NUMBER
|
||||
```
|
||||
|
||||
For any number, use `bc`.
|
||||
|
||||
|
||||
```sh
|
||||
fortune | md5sum | cut -d' ' -f1 | tr [:lower:] [:upper:] | bc
|
||||
```
|
||||
|
||||
- Inputting base 16 uses `ibase=16`.
|
||||
- Outputting base 10 uses `ibase=10`
|
||||
|
||||
```sh
|
||||
echo 'ibase=16;' $(echo cbb478ac825f0dce7671254be035d0bc | tr [:lower:] [:upper:]) | bc
|
||||
```
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: "radicale and nginx"
|
||||
tags: [ "data", "calendar" ]
|
||||
requires: [ "nginx", "certbot" ]
|
||||
---
|
||||
|
||||
Check before you start:
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: "sc-im"
|
||||
tags: [ "TUI", "data", "spreadsheet", ".csv" ]
|
||||
requires: [ "vim basics" ]
|
||||
---
|
||||
|
||||
- [Sample file](sc-im/sample.sc)
|
||||
|
33
data/search_video_audio.md
Normal file
33
data/search_video_audio.md
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
title: "Search Video Audio"
|
||||
tags: [ "data", "video" ]
|
||||
---
|
||||
|
||||
Check subtitles available:
|
||||
|
||||
```sh
|
||||
url='https://videos.domainepublic.net/videos/watch/d9567d5b-1add-477c-bce3-a58cef84c28c'
|
||||
yt-dlp --list-subs "$url" | grep --max-count=1 '^en'
|
||||
```
|
||||
|
||||
The original language often displays with `-orig`, e.g. `en-orig (Original)`.
|
||||
|
||||
```
|
||||
Language Formats
|
||||
ar vtt
|
||||
az vtt
|
||||
bg vtt
|
||||
ca vtt
|
||||
cs vtt
|
||||
da vtt
|
||||
de vtt
|
||||
el vtt
|
||||
en vtt
|
||||
```
|
||||
|
||||
Search youtube.com for videos on a topic, and download subtitles:
|
||||
|
||||
```sh
|
||||
url="$(ytfzf -I l "$search" )" && \
|
||||
yt-dlp --write-subs --sub-format 'ass/srt/best/vtt' --sub-langs "en.*" --skip-download "$url"
|
||||
```
|
24
data/soft-serve/maintenance.md
Normal file
24
data/soft-serve/maintenance.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "Soft Serve Maintenance"
|
||||
tags: [ "data", "git server", "maintenance" ]
|
||||
requires: [ "git", "nginx" ]
|
||||
---
|
||||
|
||||
Over time git repositories become bloated with old data, but never get cleaned.
|
||||
I can't find an official way to clean up the crud, so I did this:
|
||||
|
||||
```sh
|
||||
usermod -aG soft-serve $USER
|
||||
# Log out and back in for this to take effect.
|
||||
|
||||
cd /var/lib/soft-serve/data/repos
|
||||
sudo chmod -R g+w *
|
||||
git config --global --add safe.directory '*'
|
||||
du -sh *.git
|
||||
for repo in *.git; do
|
||||
git -C "$repo" gc
|
||||
done
|
||||
du -sh *.git
|
||||
$EDITOR ~/.gitconfig
|
||||
# You should remove having everything marked 'safe'.
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: "Soft Serve through https"
|
||||
tags: [ "data", "git server", "lfs" ]
|
||||
requires: [ "git", "nginx" ]
|
||||
---
|
||||
|
||||
## `http` Setup
|
||||
@ -33,7 +34,7 @@ Restart the `soft-serve` service, then check it's working by cloning from localh
|
||||
git clone http://localhost:23232/${some_repo}.git
|
||||
```
|
||||
|
||||
## `https` Setup
|
||||
### `https` Setup
|
||||
|
||||
Put this file at `/etc/nginx/sites-enabled/$DOMAIN.tld`, then set up standard certificates with [nginx](../networking/website/nginx.md).
|
||||
|
||||
@ -67,3 +68,4 @@ Put this file at `/etc/nginx/sites-enabled/$DOMAIN.tld`, then set up standard ce
|
||||
}
|
||||
|
||||
```
|
||||
|
8
data/soft.md
Normal file
8
data/soft.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "Soft-Serve"
|
||||
tags: [ "data", "git server", "lfs", "TUI" ]
|
||||
requires: [ "git", "nginx" ]
|
||||
---
|
||||
|
||||
- [Soft-Serve with https](soft-serve/soft_https.md)
|
||||
- [Maintenance](soft-serve/maintenance.md)
|
@ -11,6 +11,7 @@ Select a keymap, and create a new custom map.
|
||||
|
||||
```sh
|
||||
su root
|
||||
ls /usr/share/kbd/keymaps/i386/qwerty/
|
||||
|
||||
basemap=/usr/share/kbd/keymaps/i386/qwerty/pl1.map.gz
|
||||
newmap=/usr/share/kbd/keymaps/custom.map.gz
|
||||
|
20
networking/bad_horse.md
Normal file
20
networking/bad_horse.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
title: "Mapping the Net"
|
||||
tags: [ "networking", "graph", "fun" ]
|
||||
---
|
||||
|
||||
Find the path to a domain:
|
||||
|
||||
```sh
|
||||
domain=bad.horse
|
||||
max_hops=50
|
||||
|
||||
tracepath -m $maximum_hops $domain
|
||||
```
|
||||
|
||||
If you're on Debian, you can use `graph-easy` and `dothost` to make an instant diagram:
|
||||
|
||||
```sh
|
||||
domain=dice.camp
|
||||
dothost $domain | graph-easy --boxart
|
||||
```
|
@ -3,7 +3,7 @@ title: "tor"
|
||||
tags: [ "networking" ]
|
||||
---
|
||||
|
||||
# Get a hostname
|
||||
# Get a Hostname
|
||||
|
||||
```bash
|
||||
sudo vim /etc/tor/torrc
|
||||
|
@ -23,7 +23,8 @@ Using four spaces will not work!
|
||||
|
||||
## Dependency Files
|
||||
|
||||
Now we've made a `README.md` file, we can show how a makefile looks in the README:
|
||||
Now we've made a `README.md` file, we can show how a makefile looks in the README file.
|
||||
Add these lines to the `Makefile`:
|
||||
|
||||
```make
|
||||
README.md: Makefile
|
||||
@ -44,7 +45,7 @@ Note the order:
|
||||
|
||||
Notice that the file above can print into the README by using `echo "" >> $@`.
|
||||
The `$@` stands for 'the file which we want', and `$<` stands for 'the first dependency file'.
|
||||
The `make` program starts by replacing those variables, and the result it:
|
||||
The `make` program starts by replacing those variables, so when you run `make`, the program looks like this:
|
||||
|
||||
```make
|
||||
README.md: Makefile
|
||||
@ -54,7 +55,6 @@ README.md: Makefile
|
||||
cat Makefile >> README.md
|
||||
echo '```' >> README.md
|
||||
|
||||
|
||||
```
|
||||
|
||||
| Sigil | Meaning |
|
||||
@ -71,7 +71,6 @@ README.md: Makefile
|
||||
|
||||
You can assign a variable normally, but must refer to it in brackets.
|
||||
|
||||
|
||||
```make
|
||||
storage_directory = backups
|
||||
|
||||
@ -182,4 +181,3 @@ In this case, the makefile can see that `backup` depends on the current backup f
|
||||
- [File patterns](Makefiles/patterns.md)
|
||||
- [Makefile graphs](Makefiles/graph-easy.md)
|
||||
- [In-build help](Makefiles/help.md)
|
||||
- [Makefile graphs](Makefiles/graph-easy.md)
|
||||
|
@ -8,13 +8,13 @@ Running `make help` will search for text which starts with `## ` and show what t
|
||||
|
||||
```make
|
||||
.PHONY: help
|
||||
help: ## Print the help message
|
||||
help: ## Print the help message.
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[0-9a-zA-Z._-]+:.*?## / {printf "\033[36m%s\033[0m : %s\n", $$1, $$2}' $(MAKEFILE_LIST) | \
|
||||
sort | \
|
||||
column -s ':' -t
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Remove generated files
|
||||
clean: ## Remove generated files.
|
||||
$(RM) $(defaults)
|
||||
```
|
||||
|
||||
|
32
system/managing_groups.md
Normal file
32
system/managing_groups.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: "Managing Groups"
|
||||
tags: [ "system" ]
|
||||
---
|
||||
|
||||
Check which groups you are in, and which are available:
|
||||
|
||||
```sh
|
||||
cat /etc/group
|
||||
groups
|
||||
cat /etc/group | grep $USER
|
||||
```
|
||||
|
||||
Remove yourself from all groups, and add yourself back to only `wheel`, `audio`, and your own group:
|
||||
|
||||
```sh
|
||||
sudo usermod --groups wheel,audio,$USER
|
||||
```
|
||||
|
||||
Add yourself to the `wheel` group:
|
||||
|
||||
```sh
|
||||
su root -c "usermod --append --groups wheel $USER"
|
||||
```
|
||||
Add yourself to the `network` group:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG network $USER
|
||||
```
|
||||
|
||||
The changes will not take effect until you log in again, so reboot or log into `localhost` with [ssh](../networking/ssh.md).
|
||||
|
@ -1,21 +1,16 @@
|
||||
---
|
||||
title: "virtualbox"
|
||||
tags: [ "system" ]
|
||||
requires: [ "Managing Groups" ]
|
||||
---
|
||||
# Setup
|
||||
|
||||
## Arch Linux
|
||||
Load the modules (or just reboot):
|
||||
|
||||
```sh
|
||||
sudo pacman -S virtualbox-host-modules-arch virtualbox-guest-iso
|
||||
```
|
||||
|
||||
```sh
|
||||
sudo modprobe vboxdrv
|
||||
```
|
||||
|
||||
```sh
|
||||
# vboxreload
|
||||
su root
|
||||
modprobe vboxdrv
|
||||
vboxreload
|
||||
```
|
||||
|
||||
Make dd image into vdi
|
||||
@ -30,7 +25,13 @@ If this doesn't work, try to make a new bite size with just
|
||||
sudo dd if=image.dd of=image2.dd bs=512 conv=sync
|
||||
```
|
||||
|
||||
## CLI Management
|
||||
## Arch Linux
|
||||
|
||||
```sh
|
||||
pacman -S virtualbox-host-modules-arch virtualbox-guest-iso
|
||||
```
|
||||
|
||||
# CLI Management
|
||||
|
||||
List boxes:
|
||||
|
||||
@ -50,22 +51,19 @@ To pause the machine:
|
||||
VBoxManage controlvm "rata" pause --type headless
|
||||
```
|
||||
|
||||
You can do a number of things to virtualboxes this way:
|
||||
You can do a number of things to the 'virtual boxes' this way:
|
||||
|
||||
- startvm
|
||||
|
||||
- pause
|
||||
|
||||
- resume
|
||||
|
||||
- poweroff
|
||||
- `startvm`
|
||||
- `pause`
|
||||
- `resume`
|
||||
- `poweroff`
|
||||
|
||||
## Creating Disks
|
||||
|
||||
Creating a VM requires registering it:
|
||||
|
||||
```sh
|
||||
VBoxManage createvm --name Ubuntu19.04 --register --ostype Ubuntu
|
||||
VBoxManage createvm --name Ubuntu19.04 --register --ostype Ubuntu
|
||||
```
|
||||
|
||||
```sh
|
||||
@ -78,6 +76,7 @@ VBoxManage storagectl Ubuntu19.04 -name IDE --add ide --controller PIIX4 --boot
|
||||
|
||||
Create just a disk with:
|
||||
|
||||
VBoxManageg createhd --filename Ubuntu16.04 --size 5120
|
||||
|
||||
```sh
|
||||
VBoxManage createhd --filename "$diskname" --size 5120
|
||||
```
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user