Reorganize notes
This commit is contained in:
parent
c516e9c3ad
commit
62d3bbcb44
39
bin/notes
39
bin/notes
|
@ -1,36 +1,33 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Read notes files from ~/.configs_pointer/notes
|
print_help() {
|
||||||
if [[ $1 =~ '-h' ]]; then
|
cat <<HELP
|
||||||
printf 'Open notes files from ~/.configs_pointer/notes\n'
|
Quickly open notes files from ~/.configs_pointer/notes
|
||||||
|
|
||||||
|
No arguments required
|
||||||
|
HELP
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n "$1" ]]; then
|
||||||
|
print_help
|
||||||
exit 0
|
exit 0
|
||||||
elif ! [[ -h ~/.configs_pointer ]]; then
|
elif ! [[ -h ~/.configs_pointer ]]; then
|
||||||
cat <<ERR
|
printf 'Please set up a symlink ~/.config_pointer to the configs directory\n'
|
||||||
Pointer to configs not found
|
|
||||||
Please set up a symlink ~/.config_pointer to the configs directory
|
|
||||||
ERR
|
|
||||||
exit 1
|
|
||||||
elif ! command -v fzf &>/dev/null; then
|
|
||||||
printf 'Requires fzf\n'
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cd ~/.configs_pointer/notes || exit 2
|
||||||
# Fzf for notes file
|
declare -r notes_file="$(fd -e 'md' | fzf)"
|
||||||
if command -v fd &> /dev/null; then
|
|
||||||
notes_file=~/.configs_pointer/notes/"$(fd '.md' ~/.configs_pointer/notes -x basename | fzf)"
|
|
||||||
else
|
|
||||||
notes_file="$(find ~/.configs_pointer/notes -type f | fzf)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Use best available pagenator
|
# Use best available pagenator
|
||||||
if command -v nvim &>/dev/null; then
|
if [[ -z "$notes_file" ]]; then
|
||||||
|
printf "No note file selected\n"
|
||||||
|
exit 1
|
||||||
|
elif command -v nvim &>/dev/null; then
|
||||||
nvim -R "${notes_file}"
|
nvim -R "${notes_file}"
|
||||||
elif command -v vim &>/dev/null; then
|
elif command -v vim &>/dev/null; then
|
||||||
vim -R "${notes_files}"
|
vim -R "${notes_file}"
|
||||||
elif command -v bat &>/dev/null; then
|
elif command -v bat &>/dev/null; then
|
||||||
bat --paging=always "${notes_file}"
|
bat --paging=always "${notes_file}"
|
||||||
else
|
else
|
||||||
less "${notes_file}"
|
less "${notes_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
248
notes/futher_intallation/further_installation_macos.md
Normal file
248
notes/futher_intallation/further_installation_macos.md
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
Further recommendations to set your system, after having already run the
|
||||||
|
`install.sh` script. A package manager is the cleanest way to install any of the
|
||||||
|
apps listed here. Unless specified, these are all open source
|
||||||
|
|
||||||
|
# Mac OS
|
||||||
|
|
||||||
|
## Shell
|
||||||
|
|
||||||
|
Non-graphic open source applications. Use `brew install --formula` unless
|
||||||
|
otherwise specified
|
||||||
|
|
||||||
|
`pbpaste` except for images. Redirect output to file with `pngpaste - > img.png`
|
||||||
|
|
||||||
|
```
|
||||||
|
pngpaste
|
||||||
|
```
|
||||||
|
|
||||||
|
GNU's `coreutils`. Apple has most by default, though they're very outdated
|
||||||
|
|
||||||
|
```
|
||||||
|
coreutils
|
||||||
|
```
|
||||||
|
|
||||||
|
File manager for quickly jumping around directories. Not essential
|
||||||
|
|
||||||
|
```
|
||||||
|
vifm
|
||||||
|
```
|
||||||
|
|
||||||
|
Quickly search stackoverflow for answers to any query
|
||||||
|
|
||||||
|
```
|
||||||
|
so
|
||||||
|
```
|
||||||
|
|
||||||
|
Checks your shell scripts and suggests fixes to potential errors
|
||||||
|
|
||||||
|
```
|
||||||
|
shellcheck
|
||||||
|
```
|
||||||
|
|
||||||
|
Non-graphic image manipulator. Very useful in scripts and often a dependency
|
||||||
|
|
||||||
|
```
|
||||||
|
imagemagick
|
||||||
|
```
|
||||||
|
|
||||||
|
A much better python REPL and integrates nicely with vim's IPython plugin
|
||||||
|
|
||||||
|
```
|
||||||
|
ipython
|
||||||
|
```
|
||||||
|
|
||||||
|
The largest support converting documents types, such as markdown to pdf
|
||||||
|
|
||||||
|
```
|
||||||
|
pandoc
|
||||||
|
```
|
||||||
|
|
||||||
|
`ctags` with a lot more language support
|
||||||
|
|
||||||
|
```
|
||||||
|
universal-ctags
|
||||||
|
```
|
||||||
|
|
||||||
|
`cut`, `sed`, `grep`, `xargs`, `printf`, etc, for all your stream editing needs
|
||||||
|
|
||||||
|
```
|
||||||
|
gawk
|
||||||
|
```
|
||||||
|
|
||||||
|
Foreign filesystems on mac. `sshfs` from `brew install gromgit/fuse/sshfs-mac`
|
||||||
|
|
||||||
|
```
|
||||||
|
sshfs macfuse
|
||||||
|
```
|
||||||
|
|
||||||
|
A javascript runtime for servers. It's also useful for shell scripts
|
||||||
|
|
||||||
|
```
|
||||||
|
node
|
||||||
|
```
|
||||||
|
|
||||||
|
### Applications
|
||||||
|
Applications that should be considered for installation on any mac. Everything
|
||||||
|
listed here is open source. Use `brew install --cask` unless otherwise specified
|
||||||
|
|
||||||
|
Hotkey daemon for MacOS. Config files can be set up with the install script.
|
||||||
|
Either `brew services` or launchd can be used to start `skhd` automatically
|
||||||
|
|
||||||
|
```
|
||||||
|
skhd ✔️
|
||||||
|
```
|
||||||
|
|
||||||
|
The most widely used media player capable of decoding almost any format
|
||||||
|
|
||||||
|
```
|
||||||
|
vlc ✔️
|
||||||
|
```
|
||||||
|
|
||||||
|
Pairs with `vlc` to watch videos with others remotely
|
||||||
|
|
||||||
|
```
|
||||||
|
syncplay
|
||||||
|
```
|
||||||
|
|
||||||
|
Really powerful flashcard memorization software
|
||||||
|
|
||||||
|
```
|
||||||
|
anki
|
||||||
|
```
|
||||||
|
|
||||||
|
Pdf reader with contents lists and double display
|
||||||
|
|
||||||
|
```
|
||||||
|
skim
|
||||||
|
```
|
||||||
|
|
||||||
|
Installs both a gui version of vim and a more featured non-graphic version too
|
||||||
|
|
||||||
|
```
|
||||||
|
[nvchad]
|
||||||
|
[VapourNvim]
|
||||||
|
macvim
|
||||||
|
```
|
||||||
|
|
||||||
|
Best torrent client. No-nonsense and a nice interface
|
||||||
|
|
||||||
|
```
|
||||||
|
qbittorrent
|
||||||
|
```
|
||||||
|
|
||||||
|
Output or capture system-audio by providing a virtual output device
|
||||||
|
|
||||||
|
```
|
||||||
|
blackhole-2ch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Power tools
|
||||||
|
Heavier applications that should be installed only on capable systems. Use `brew
|
||||||
|
install --cask` unless otherwise specified. These are all open source
|
||||||
|
|
||||||
|
Full video editor that puts iMovie to shame. Exports require a lot of cpu power
|
||||||
|
|
||||||
|
```
|
||||||
|
shotcut
|
||||||
|
```
|
||||||
|
|
||||||
|
Emulator for any operating system. Configuration is complicated. See examples in
|
||||||
|
`shell/qemu/`
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu ✔️
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux subsystem for mac. Essentially qemu + sshfs automated
|
||||||
|
|
||||||
|
```
|
||||||
|
lima
|
||||||
|
```
|
||||||
|
|
||||||
|
Image editing similar to Photoshop, except free and with wider platform support
|
||||||
|
|
||||||
|
```
|
||||||
|
gimp
|
||||||
|
```
|
||||||
|
|
||||||
|
Full latex support. Vim configuration and snippets are already setup. Takes
|
||||||
|
almost 10G for a base installation and runs hot
|
||||||
|
|
||||||
|
```
|
||||||
|
mactex ✔️
|
||||||
|
```
|
||||||
|
|
||||||
|
### Proprietary
|
||||||
|
|
||||||
|
Screenshot tool to fill the gap between Mac OS's screenshots and gimp
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install --cask skitch
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternative screenshot tool, with a few more markup options
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install --cask flameshot
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Extra nonsense
|
||||||
|
|
||||||
|
Make banners for titles
|
||||||
|
|
||||||
|
```
|
||||||
|
figlet
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mapping from linux
|
||||||
|
|
||||||
|
Macs aren't even close to Linux in virtualisation capabilities, window managers,
|
||||||
|
and customizability in general. However, if you're unfortunate enough to find
|
||||||
|
yourself with a macbook, all is not lost. Here's a rough porting guide:
|
||||||
|
|
||||||
|
| sWayland | MacOS |
|
||||||
|
| --------------------- | -------- |
|
||||||
|
| SwayWM | [Yabai](https://github.com/koekeishiya/yabai) |
|
||||||
|
| xRemap | [Karabiner-Elements](https://karabiner-elements.pqrs.org/) |
|
||||||
|
| ~/.config/sway/config | [skhd](https://github.com/koekeishiya/skhd) |
|
||||||
|
| swhkd | [skhd](https://github.com/koekeishiya/skhd) |
|
||||||
|
| wtype | [skhd](https://github.com/koekeishiya/skhd) |
|
||||||
|
| systemd | Launchd |
|
||||||
|
| Zathura | [Skim](https://skim-app.sourceforge.io/) |
|
||||||
|
| Fuzzel | [Choose](https://github.com/chipsenkbeil/choose) or Spotlight |
|
||||||
|
| udisksctl | `diskutil`
|
||||||
|
| ~/.local/share/fonts | FontBook |
|
||||||
|
| wl-clipboard | `pbcopy` `pbpaste` |
|
||||||
|
| sshd | System Preference -> Sharing -> Remote Login |
|
||||||
|
| Super/Ctrl | Command |
|
||||||
|
| Alt | Opt |
|
||||||
|
|
||||||
|
For Xorg users, `yabai` is to `skhd` what `bspwm` is to `sxhkd`. Also `launchd`
|
||||||
|
is wayyy less capable than `systemd` and rarely gets used. The `launchd` script
|
||||||
|
in `./bin` wraps around all the commands you'll ever need
|
||||||
|
|
||||||
|
To use open source apps, run `sudo spctl --master-disable`, then head to System
|
||||||
|
Preferences -> Security & Privacy -> General and select Anywhere at the bottom.
|
||||||
|
You can check it's working with `spctl --status`
|
||||||
|
|
||||||
|
While you're here, you can go under Software Updates and uncheck everything
|
||||||
|
|
||||||
|
## Window managers
|
||||||
|
|
||||||
|
MacOS only allows the default Quartz Compositor, a floating window manager with
|
||||||
|
too many animations and almost no keyboard controls. There are two open source
|
||||||
|
tiling window managers, which are just scripts overtop Quartz Compositor as
|
||||||
|
alternatives. [Amethyst](https://github.com/ianyh/Amethyst) and
|
||||||
|
[Yabai](https://github.com/koekeishiya/yabai)
|
||||||
|
|
||||||
|
Amethyst provides basic tiling of windows and basic keyboard controls. Yabai is
|
||||||
|
effectively a port of bspwm to MacOS and has much more extensive configuration
|
||||||
|
than Amethyst, notably controlling workspaces. Unfortunately they don't hold a
|
||||||
|
candle to Linux managers. Both can be very laggy and Yabai specifically often
|
||||||
|
freezes up for a few seconds, though these are the only options.
|
||||||
|
|
||||||
|
To use Yabai, boot into recovery mode, and disable SIP [as explained
|
||||||
|
here](https://github.com/koekeishiya/yabai/wiki/Disabling-System-Integrity-Protection).
|
||||||
|
Despite what apple says, this doesn't make the system immediately explode.
|
||||||
|
Actually there's no difference at all, except being able to use Yabai
|
175
notes/futher_intallation/futher_installation_linux.md
Normal file
175
notes/futher_intallation/futher_installation_linux.md
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
# Linux
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
Many scripts assume you have access to [Meslo LGM
|
||||||
|
NerdFont](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/Meslo/M).
|
||||||
|
These can be replaced easily with any other nerd font. Other fonts may lack
|
||||||
|
support for the right character set
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mv -i downloaded-fonts/* ~/.local/share/fonts
|
||||||
|
# mv -i downloaded-fonts/* /usr/local/share/fonts
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [ArchWiki](https://wiki.archlinux.org/title/fonts#Manual_installation)
|
||||||
|
for more information. TexLive downloads a lot of additional fonts by default too
|
||||||
|
|
||||||
|
## xRemap
|
||||||
|
|
||||||
|
Remapping keys is done through `xremap`. Despite the name, it works flawlessly
|
||||||
|
on Wayland, at least in Sway
|
||||||
|
|
||||||
|
Depending on your environment, you need to install a different binary, all of
|
||||||
|
which are available through `cargo`. For example `cargo install xremap
|
||||||
|
--features sway`. Check [here for more
|
||||||
|
options](https://github.com/k0kubun/xremap#installation).
|
||||||
|
|
||||||
|
If you're using systemd, run the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
# ln -s ~/.configs_pointer/xremap/config{_console,}.yml
|
||||||
|
# mkdir -p /etc/xremap
|
||||||
|
# ln -s {~/.configs_pointer,/etc}/xremap/config.yml
|
||||||
|
# cp ~/.configs_pointer/systemd/xremap.service /etc/systemd/system/xremap.service
|
||||||
|
# cp ~/.cargo/bin/xremap /usr/local/bin/xremap
|
||||||
|
# systemctl enable xremap.service
|
||||||
|
# systemctl start xremap.service
|
||||||
|
# switch_keyboards.sh pc
|
||||||
|
```
|
||||||
|
|
||||||
|
You can toggle between Mac-style keyboard and standard keyboard with
|
||||||
|
`switch_keyboards.sh` see the doc-comment `vi $(which switch_keyboards.sh)` for
|
||||||
|
more information
|
||||||
|
|
||||||
|
`sway/config` acts as a hotkey daemon and `wtype` can synthesize input
|
||||||
|
|
||||||
|
## Sway
|
||||||
|
|
||||||
|
To run sway, install the `sway` and `swaylock` packages. Both configs reference
|
||||||
|
`default_wallpaper.png` in their respective directories. Put your wallpaper
|
||||||
|
there or change the corresponding `config` file
|
||||||
|
|
||||||
|
If sway is acting up, try setting/unsetting `WAYLAND_DISPLAY` and `SWAYSOCK`.
|
||||||
|
`swaymsg` also takes an `-s` option which can specify the socket manually
|
||||||
|
|
||||||
|
Sway doesn't adjust the gamma on external displays. Compared to MacOS,
|
||||||
|
everything looks very washed-out and low contrast. Using `wl-sunset` with `-t
|
||||||
|
4000 -T 6500 -g 0.9` brings MacOS-like gamma curves
|
||||||
|
|
||||||
|
For more information about sway, read the [i3 User's
|
||||||
|
Guide](https://i3wm.org/docs/userguide.html). Particularly chapters 3 and 4 are
|
||||||
|
very important for sway
|
||||||
|
|
||||||
|
## Multilingual input (fcitx)
|
||||||
|
|
||||||
|
IME-style inputs require a complicated setup on wayland. The method described
|
||||||
|
here unfortunately scales like Xwayland. That is to say it's very blurry on a
|
||||||
|
HiDPI display. Also, IMEs don't work in Alacritty yet. Consider [foot
|
||||||
|
terminal](https://codeberg.org/dnkl/foot) if this is important
|
||||||
|
|
||||||
|
If you only need an IME in Chromium, [Google Input
|
||||||
|
Tools](https://chrome.google.com/webstore/detail/google-input-tools/mclkkofklkfljcocdinagocijmpgbhab)
|
||||||
|
is a pretty decent solution. It scales properly on wayland and doesn't require a
|
||||||
|
spotty setup. However, it doesn't work in the search bar and makes network calls
|
||||||
|
for kanji lookups, which can be really slow
|
||||||
|
|
||||||
|
Otherwise you can use fcitx5. Choose a supported IME based on what language you
|
||||||
|
need [here](https://wiki.archlinux.org/title/Input_method). For the example
|
||||||
|
below we'll install Mozc
|
||||||
|
|
||||||
|
```bash
|
||||||
|
please pacman -S fcitx5 fcitx5-configtool fcitx5-gtk fcitx5-qt fcitx5-mozc
|
||||||
|
please pacman -S gtk4 # For Chromium support
|
||||||
|
```
|
||||||
|
|
||||||
|
Next add these lines to `/etc/environment`
|
||||||
|
|
||||||
|
```
|
||||||
|
GTK_IM_MODULE=fcitx
|
||||||
|
QT_IM_MODULE=fcitx
|
||||||
|
XMODIFIERS=@im=fcitx
|
||||||
|
MOZ_ENABLE_WAYLAND=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Currently, Chromium will only interface with fcitx5 when it's running on the
|
||||||
|
non-default gtk4. Add `--gtk-version=4` to `~/.config/chromium-flags.conf`. As
|
||||||
|
of writing, this breaks Chromium's built-in file manager, the one for picking
|
||||||
|
files. Use Firefox for a better fcitx5 experience
|
||||||
|
|
||||||
|
Open fcitx5-configtool to set the required keyboards and change the global
|
||||||
|
hotkey. For Mozc, you'd move the Mozc keyboard to the left. Not the other
|
||||||
|
Japanese keyboards, those are not IME-based
|
||||||
|
|
||||||
|
You may need to reboot wayland or possibly the entire system. Fcitx5 will now be
|
||||||
|
available will the following command. Consider adding the following to
|
||||||
|
`sway/config` if you want it on startup, or use `<M-i>` to toggle in on/off
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fcitx5 -d --replace
|
||||||
|
```
|
||||||
|
|
||||||
|
## AV1 media
|
||||||
|
|
||||||
|
AV1 is the hottest new codec on the block, providing compression levels better
|
||||||
|
than h265. I've seen it 200x smaller than png, with the same resolution and
|
||||||
|
color space
|
||||||
|
|
||||||
|
To store images as avif, use `magick convert my_image_name.{png,avif}`. `viu`
|
||||||
|
has no support for avif. `imv` supports it out of the box. `vimiv` requires a qt
|
||||||
|
plugin for support:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
please pacman -S libavif
|
||||||
|
# Get the latest release from below, for example
|
||||||
|
# https://github.com/novomesk/qt-avif-image-plugin/releases/latest
|
||||||
|
curl -LO 'https://github.com/novomesk/qt-avif-image-plugin/archive/refs/tags/v0.5.0.tar.gz'
|
||||||
|
tar xf qt-avif-image-plugin-0.5.0.tar.gz
|
||||||
|
cd qt-avif-image-plugin-0.5.0
|
||||||
|
./build_libqavif_dynamic.sh
|
||||||
|
please make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chromium
|
||||||
|
|
||||||
|
Chromium does not support screen sharing by default on wayland. To add support
|
||||||
|
go into `chrome://flags` and enable the "WebRTC PipeWire support" flag. Next
|
||||||
|
download the following a reboot to allow screen sharing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
please pacman -S xdg-desktop-portal-wlr libpipewire02
|
||||||
|
```
|
||||||
|
|
||||||
|
Consider disabling "Continue running background apps when Chromium is closed" in
|
||||||
|
settings
|
||||||
|
|
||||||
|
Fix the default fonts in `chrome://settings/fonts`. These are the fallback fonts
|
||||||
|
|
||||||
|
For the really daring, change your download location to `/dev/shm`. This is a
|
||||||
|
ramdisk which clears all its content on reboot
|
||||||
|
|
||||||
|
## Firefox
|
||||||
|
|
||||||
|
Firefox will start on xorg by default, unless the `MOZ_ENABLE_WAYLAND=1`
|
||||||
|
environment variable is set. Incognito is enabled through the `--private-window`
|
||||||
|
flag
|
||||||
|
|
||||||
|
Firefox uses `about:config` stored in
|
||||||
|
`~/.mozilla/firefox/<random-hash>.default-release/prefs.js`. These are the
|
||||||
|
equivalent of Chromium flags. For these configs, simply switch
|
||||||
|
`ui.key.menuAccessKeyFocuses` to false, to avoid conflicts with xremap
|
||||||
|
|
||||||
|
## Backlights
|
||||||
|
|
||||||
|
Laptops usually control the backlight via apci. One program to control this is
|
||||||
|
[light](https://github.com/haikarainen/light). By default light requires the use
|
||||||
|
of root privileges to modify devices. Use systemd rules and the video group to
|
||||||
|
allow unprivileged users to run it normally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -LO 'https://raw.githubusercontent.com/haikarainen/light/master/90-backlight.rules'
|
||||||
|
please mkdir -p /usr/lib/udev/rules.d
|
||||||
|
please cp 90-backlight.rules /usr/lib/udev/rules.d
|
||||||
|
# Add your user to the video group
|
||||||
|
please usermod -aG video emiliko
|
||||||
|
```
|
34
notes/linux/aerc.md
Normal file
34
notes/linux/aerc.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Aerc - Allegedly "the world's best email client"
|
||||||
|
A terminal email client that's pretty decent out-of-the-box. Configuration is
|
||||||
|
divided between 3 files, the most important one is accounts.conf described here
|
||||||
|
|
||||||
|
```bash
|
||||||
|
please pacman -S aerc w3m dante
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll need an app password to login. This can be put directly after the email.
|
||||||
|
Gmail has one [here for
|
||||||
|
example](https://support.google.com/accounts/answer/185833?hl=en)
|
||||||
|
|
||||||
|
```
|
||||||
|
source = `imaps://emiliko%40gmail.com:passwordhere123@imap.gmail.com:993`
|
||||||
|
```
|
||||||
|
|
||||||
|
Or alternatively use the `source-cred-cmd` to retrieve a password through a
|
||||||
|
program like `pass`, as shown below
|
||||||
|
|
||||||
|
```
|
||||||
|
[Gmail]
|
||||||
|
source = `imaps://emiliko%40gmail.com@imap.gmail.com:993`
|
||||||
|
source-cred-cmd = `pass show gmail/primary/app_password`
|
||||||
|
outgoing = `smtps+plain://emiliko%40gmail.com@smtp.gmail.com:465`
|
||||||
|
outgoing-cred-cmd = `pass show gmail/primary/app_password`
|
||||||
|
default = INBOX
|
||||||
|
from = Emiliko Mirror <emiliko@gmail.com>
|
||||||
|
copy-to = Sent
|
||||||
|
check-mail = 1m
|
||||||
|
```
|
||||||
|
|
||||||
|
For other email providers, look up their server names and port, for example
|
||||||
|
Fastmail has them [listed
|
||||||
|
here](https://www.fastmail.help/hc/en-us/articles/1500000278342)
|
28
notes/linux/bluetooth_headphones.md
Normal file
28
notes/linux/bluetooth_headphones.md
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Airpods - bluetooth audio
|
||||||
|
Bluetooth headsets may be unusable with pulse audio by default. Particular
|
||||||
|
symptoms include cutting out and compressed playback. This is completely
|
||||||
|
independent of the speaker setup, so it won't mess up the config there
|
||||||
|
|
||||||
|
Start by finding your bluetooth card's name with
|
||||||
|
|
||||||
|
$ pactl list | grep -Pzo '.*bluez_card(.*\n)*'
|
||||||
|
|
||||||
|
This also shows the latency in the output section. It should be 0. Now increase
|
||||||
|
the latency. 50000 is a good choice for airpods pro
|
||||||
|
|
||||||
|
$ pactl set-port-latency-offset bluez_card.00_8A_76_4D_9B_BB headphone-output 50000
|
||||||
|
$ systemctl restart bluetooth
|
||||||
|
|
||||||
|
That should fix the cutting out issues. Not connect the airpods
|
||||||
|
|
||||||
|
$ bluetoothctl
|
||||||
|
[bt]# power on
|
||||||
|
[bt]# default-agent
|
||||||
|
[bt]# scan on
|
||||||
|
[NEW] Device 00:8A:76:4D:9B:BB Anna’s Airpods
|
||||||
|
[bt]# trust 00:8A:76:4D:9B:BB
|
||||||
|
[bt]# pair 00:8A:76:4D:9B:BB
|
||||||
|
[bt]# connect 00:8A:76:4D:9B:BB
|
||||||
|
|
||||||
|
You may need to redirect pulse audio's output to the airpods. Referenced from
|
||||||
|
[here](https://askubuntu.com/questions/475987/a2dp-on-pulseaudio-terrible-choppy-skipping-audio)
|
177
notes/linux/gnupg.md
Normal file
177
notes/linux/gnupg.md
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
# GnuPG
|
||||||
|
Key files are a secure method for certifying credentials digitally. Everything
|
||||||
|
is stored in `~/.gnupg` and controlled through `gpg`. It's quite complicated...
|
||||||
|
See `tldr gpg` for encryption, [devhints](https://devhints.io/gnupg) for a
|
||||||
|
cheat sheet, the [Archwiki](https://wiki.archlinux.org/title/GnuPG) for a
|
||||||
|
technical explanation and the [Debian wiki](https://wiki.debian.org/Subkeys) for
|
||||||
|
a newbie-friendly one
|
||||||
|
|
||||||
|
Terminology:
|
||||||
|
|
||||||
|
* Public key - The one to share
|
||||||
|
* Private key - The one to not share
|
||||||
|
* Primary key - ??
|
||||||
|
* Subkey - ??
|
||||||
|
* Keygrip - The name of the key file
|
||||||
|
* Key ID - The last few (8-16) characters of a fingerprint
|
||||||
|
* Fingerprint - A unique identifier for a key
|
||||||
|
* Keyring - Your entire collection of public or private keys
|
||||||
|
* User ID - Email, part of name, Key ID, or Fingerprint of a key
|
||||||
|
|
||||||
|
Consider this example output:
|
||||||
|
```bash
|
||||||
|
$ gpg --list-secret-keys --with-subkey-fingerprint --with-keygrip --keyid-format=long
|
||||||
|
|
||||||
|
# ///--- Short for "secret key". It's "pub" for public keys
|
||||||
|
# vvv vvvvvvvvvvvvvvvv Key ID
|
||||||
|
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
|
||||||
|
> DDEEDF222222222222222222ABCDEFG123456789
|
||||||
|
# ^^^^^^^^^^^^^^^^ Key ID also here
|
||||||
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint
|
||||||
|
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
|
||||||
|
# Key is ~/.gnupg/private-keys-v1.d/DDEBBA3482394AEE23432DEE32432BB2432432EE.key
|
||||||
|
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
|
||||||
|
# ///--- Short for "secret subkey". It's "sub" for public subkeys
|
||||||
|
# vvv vvvvvvvvvvvvvvvv Key ID
|
||||||
|
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
|
||||||
|
> 32423BDDAAAAAAAAAAAAAAAA987654321ABCDEED
|
||||||
|
# ^^^^^^^^^^^^^^^^ Key ID also here
|
||||||
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint from --with-subkey-fingerprint
|
||||||
|
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
|
||||||
|
# Key is ~/.gnupg/private-keys-v1.d/2493ADDEDDDFEFEFE23432432FDEEFDD24324232.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Providing the `--fingerprint` flag will alter the output slightly, tho it's the
|
||||||
|
same fingerprint, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
|
||||||
|
> Key fingerprint = DDEE DF22 2222 2222 2222 2222 ABCD EFG1 2345 6789
|
||||||
|
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
|
||||||
|
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
|
||||||
|
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
|
||||||
|
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
|
||||||
|
> Key fingerprint = 3242 3BDD AAAA AAAA AAAA AAAA 9876 5432 1ABC DEED
|
||||||
|
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
|
||||||
|
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating a new key
|
||||||
|
This closely follows the Archwiki, with an elliptic cipher
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg --full-gen-key --expert
|
||||||
|
> (9) ECC and ECC
|
||||||
|
> (1) Curve 25519
|
||||||
|
> 1y # Optional, 1 year is recommended
|
||||||
|
> Your Name # This will be visible in the public key
|
||||||
|
> emiliko@mami2.moe # This is also visible in the public key
|
||||||
|
> No comment
|
||||||
|
> Put a password on the primary key
|
||||||
|
```
|
||||||
|
|
||||||
|
## Signing and verification
|
||||||
|
Git commits, binaries and really any file can be signed by a private key to
|
||||||
|
prove authenticity of the file. For github, you'll need to paste your public key
|
||||||
|
to your profile settings
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --list-secret-keys --keyid-format=long
|
||||||
|
gpg --armor --export <user-id> | wl-copy
|
||||||
|
```
|
||||||
|
|
||||||
|
Git commits aren't signed by default. Either explicitly sign at commit time,
|
||||||
|
with `git commit -S`, or add the following to your ~/.gitconfig. If the signing
|
||||||
|
key you specify is a subkey, add an ! mark at the end
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[user]
|
||||||
|
name = Emiliko Mirror
|
||||||
|
email = emiliko@mami2.moe
|
||||||
|
signingkey = ABCDEF1234567890
|
||||||
|
[commit]
|
||||||
|
gpgsign = true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Encryption
|
||||||
|
Gpg can encrypt pretty much anything. Consider bundling into a tarball
|
||||||
|
beforehand if it's more than one file
|
||||||
|
|
||||||
|
The `-a/--armor` flag will make sure the encrypted file is made up entirely of
|
||||||
|
ascii characters, which is easier to copy/paste than binary nonsense
|
||||||
|
|
||||||
|
Encryption can be symmetric or asymmetric. Symmetric encryption uses 1 key and a
|
||||||
|
password to encrypt. To decrypt, use the same key and re-enter the same
|
||||||
|
password
|
||||||
|
|
||||||
|
### Symmetric encryption
|
||||||
|
Symmetric encryption uses 1 key and 1 password to encrypt. To decrypt, you'll
|
||||||
|
need the same key and the same password
|
||||||
|
|
||||||
|
### Asymmetric encryption
|
||||||
|
Asymmetric encryption is meant for sending to a specific receiver. It uses 1
|
||||||
|
public key to encrypt. To decrypt, you'll need the private key pair to that
|
||||||
|
public key. `pass` uses this one
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg -e -o encrypted_file -r emiliko@mami2.moe secret_file
|
||||||
|
# Then emiliko can decrypt it with her private key
|
||||||
|
gpg -d -o secret_file encrypted_file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Moving keys
|
||||||
|
You'll want to export your keys to other devices. Ideally, you'd only export
|
||||||
|
subkeys and not the primary key. The primary key should be stored offline and
|
||||||
|
used to generate revocation certificates for compromised subkeys
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg -o pub_key.pgp -a --export emiliko@mami2.moe
|
||||||
|
gpg -o sec_key.pgp -a --export-secret-key emiliko@mami2.moe
|
||||||
|
|
||||||
|
scp pub_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
|
||||||
|
scp sec_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
|
||||||
|
|
||||||
|
gpg --import pub_key.gpg
|
||||||
|
gpg --import sec_key.gpg
|
||||||
|
|
||||||
|
```
|
||||||
|
A safer method skips the creation of any intermediary files by sending it
|
||||||
|
through ssh right away
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --export-secret-key <user-id> | ssh emiliko@192.168.0.1 'gpg --import'
|
||||||
|
# Or if you're on the receiving system
|
||||||
|
ssh emiliko@192.168.0.1 'gpg --export-secret-key emiliko@mami2.moe' | gpg --import
|
||||||
|
```
|
||||||
|
|
||||||
|
In either case, or actually whenever importing your keys, you'll need to edit
|
||||||
|
the trust level after importing it
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --list-keys # Get the Key ID here
|
||||||
|
gpg --edit-key <user-id>
|
||||||
|
> trust
|
||||||
|
> 5 # If it's your own key
|
||||||
|
> y
|
||||||
|
> quit
|
||||||
|
```
|
||||||
|
|
||||||
|
For use with `pass`, you can check if your encryption key is working by trying
|
||||||
|
to add a new password, like `pass insert -e something` and see if it succeeds
|
||||||
|
|
||||||
|
## Backing up keys
|
||||||
|
Keys should be backed up on offline, physically inaccessible, media. Usb sticks
|
||||||
|
you leave at home or a piece of paper are both good choices. For the paper
|
||||||
|
version see `paperkey`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg -o /run/media/my_usb/keys.gpg --export-options backup --export-secret-keys emiliko@mami2.moe
|
||||||
|
```
|
||||||
|
|
||||||
|
Now later, or on another device, you can restore these keys
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --import-options restore --import keys.gpg
|
||||||
|
```
|
||||||
|
|
||||||
|
Then edit the trust level, as with the other transfer methods
|
220
notes/linux/linux_networks.md
Normal file
220
notes/linux/linux_networks.md
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
# Networks
|
||||||
|
This file covers wifi and bluetooth connections on linux
|
||||||
|
|
||||||
|
Required packages for the guide:
|
||||||
|
- systemd
|
||||||
|
- NetworkManager
|
||||||
|
- `bluetoothctl`
|
||||||
|
|
||||||
|
Optional GUI tools to make this easier:
|
||||||
|
- `pacman -S nm-connection-editor`
|
||||||
|
- `pacman -S blueberry`
|
||||||
|
|
||||||
|
# Basic networks
|
||||||
|
For Archlinux, choose between NetworkManager and netctl for your networking
|
||||||
|
needs. NetworkManager comes from the GNOME project and is fully feature packed
|
||||||
|
from the getgo. Netctl is a set of light shell scripts that rely on external
|
||||||
|
packages for networking, so a bit harder to install
|
||||||
|
|
||||||
|
Both can be checked with systemd
|
||||||
|
```bash
|
||||||
|
systemctl status netctl.service
|
||||||
|
systemctl status NetworkManager.service
|
||||||
|
```
|
||||||
|
|
||||||
|
**Make sure only one is running and enabled**. Using both at the same time will
|
||||||
|
result in system slowdowns, especially at boot times
|
||||||
|
|
||||||
|
## NetworkManager and netctl conflict
|
||||||
|
If your system is running some `/sys/.../subnet...` for 90s at startup, likely
|
||||||
|
netctl is trying to start up a device, though the device name has changed.
|
||||||
|
Places to check:
|
||||||
|
|
||||||
|
/etc/NetworkManager/system-connections/
|
||||||
|
cd /etc/systemd/system/multi-user.target.wants/ && rg enp0s3
|
||||||
|
vi /etc/systemd/system/multi-user.target.wants/netctl@enp4s0.service
|
||||||
|
vi netctl@enp4s0.service
|
||||||
|
|
||||||
|
If you are using both by accident, make sure to use the native disable in
|
||||||
|
addition to the systemd disable. For example, with netctl:
|
||||||
|
|
||||||
|
systemctl disable netctl
|
||||||
|
systemctl disable netctl@enp4s0.service
|
||||||
|
netctl disable enp4s0
|
||||||
|
|
||||||
|
## Public networks
|
||||||
|
Public networks often use a captive portal to make users accept their terms and
|
||||||
|
conditions
|
||||||
|
|
||||||
|
1. Connect to the network using `nmtui` or similar
|
||||||
|
2. Use a GUI browser and navigate to any site
|
||||||
|
3. If that doesn't work, try navigating to a non-https using page
|
||||||
|
4. If that doesn't work, try navigating to a site you've never visited in incognito
|
||||||
|
5. If that doesn't work, try navigating to the router at 192.168.[0-1].[0-1]
|
||||||
|
|
||||||
|
# Bluetooth
|
||||||
|
Before starting bluetooth, make sure bluetooth.service is running, otherwise
|
||||||
|
nothing will work
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl start bluetooth.service
|
||||||
|
```
|
||||||
|
|
||||||
|
You may optionally install the `blueberry` GUI package. It's quite light and
|
||||||
|
limited, though it's a good way to check if your devices are connected
|
||||||
|
|
||||||
|
## Keyboard
|
||||||
|
Start `bluetoothctl`. The command sequence to connect will look something like:
|
||||||
|
|
||||||
|
$ bluetoothctl
|
||||||
|
[bluetooth]# power on
|
||||||
|
[bluetooth]# agent off
|
||||||
|
[bluetooth]# agent KeyboardOnly
|
||||||
|
[bluetooth]# scan on
|
||||||
|
[bluetooth]# pair <MAC-ADDR>
|
||||||
|
[bluetooth]# trust <MAC-ADDR>
|
||||||
|
[bluetooth]# connect <MAC-ADDR>
|
||||||
|
[bluetooth]# quit
|
||||||
|
|
||||||
|
When you turn `scan on`, the list may explode with various mac addresses. Try to
|
||||||
|
find your keyboard amongst those. During the `pair` section, `bluetoothctl` may
|
||||||
|
prompt you with 6 digits. Type those on the keyboard and possibly hit enter
|
||||||
|
after them
|
||||||
|
|
||||||
|
See the [Archwiki page](https://wiki.archlinux.org/title/bluetooth_keyboard) for
|
||||||
|
more info
|
||||||
|
|
||||||
|
## Bluetooth headphones
|
||||||
|
This section connected AirPods Pro. Setup may differ for other devices
|
||||||
|
|
||||||
|
Start by connecting your headphones with a very similar set of steps as the
|
||||||
|
keyboard guide above. Use `default-agent` instead of `agent KeyboardOnly`. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
$ bluetoothctl
|
||||||
|
[bt]# power on
|
||||||
|
[bt]# default-agent
|
||||||
|
[bt]# scan on
|
||||||
|
[NEW] Device 00:8A:76:4D:9B:BB Anna’s Airpods
|
||||||
|
[bt]# trust 00:8A:76:4D:9B:BB
|
||||||
|
[bt]# pair 00:8A:76:4D:9B:BB
|
||||||
|
[bt]# connect 00:8A:76:4D:9B:BB
|
||||||
|
|
||||||
|
Once connected, blue headphones may cutout or just not play back anything. This
|
||||||
|
is a PulseAudio issue. The bluetooth sound latency may need to be adjusted
|
||||||
|
|
||||||
|
Start by finding your bluetooth card's name with
|
||||||
|
|
||||||
|
$ pactl list | grep -Pzo '.*bluez_card(.*\n)*'
|
||||||
|
|
||||||
|
Next increase the audio latency. 50000ms seems to work well for AirPods Pro,
|
||||||
|
though this is likely [different for other
|
||||||
|
headphones](https://askubuntu.com/questions/475987/a2dp-on-pulseaudio-terrible-choppy-skipping-audio)
|
||||||
|
|
||||||
|
$ pactl set-port-latency-offset bluez_card.00_8A_76_4D_9B_BB headphone-output 50000
|
||||||
|
$ systemctl restart bluetooth.service
|
||||||
|
|
||||||
|
Repeat the steps above, adjusting the bluetooth sound latency, until it works.
|
||||||
|
Consider using the `blueberry` GUI to quickly reconnect the headphones on each
|
||||||
|
bluetooth.service restart. Don't forget to relaunch `blueberry` every time too
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kill $(pgrep ^blueberry$) && systemctl restart bluetooth.service && blueberry &
|
||||||
|
```
|
||||||
|
|
||||||
|
# Enterprise networks
|
||||||
|
Large organizations, like universities, use enterprise security on their
|
||||||
|
networks. These require an account to login, not just a password
|
||||||
|
|
||||||
|
The guide below assumes the network's name is "UWS" and your login username is
|
||||||
|
"emiliko"
|
||||||
|
|
||||||
|
You can install the optional `nm-connection-editor` to make things easier
|
||||||
|
|
||||||
|
$ nmcli device wifi list
|
||||||
|
This should show the network you're looking for
|
||||||
|
|
||||||
|
If your network is not using PAP authentication, it may be possible to just
|
||||||
|
connect with a simple password, try:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli --ask device wifi connect UWS
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise run this line, replacing the necessary information in the line above.
|
||||||
|
Particularly `UWS`, `emiliko` and `wlan0`. For `wlan0`, find your wifi device
|
||||||
|
with `ip link`. `enp...` is usually ethernet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli connection add type wifi con-name "UWS" ifname wlan0 ssid "UWS" -- wifi-sec.key-mgmt wpa-eap 802-1x.eap ttls 802-1x.phase2-auth mschapv2 802-1x.identity "emiliko"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Option 1: With nm-connection-editor
|
||||||
|
Open `nm-connection-editor`. Go into "Wifi-Security" and make it look like:
|
||||||
|
|
||||||
|
WPA & WPA2 Enterprise
|
||||||
|
Tunnled TLS
|
||||||
|
CA Certificate: (None)
|
||||||
|
Check No CA certificate required
|
||||||
|
Inner authentication: PAP
|
||||||
|
Type in your login credentials at the bottom. Now run
|
||||||
|
|
||||||
|
## Option 2: Without nm-connection-editor
|
||||||
|
If you don't have the GUI tool `nm-connection-editor` and no way to install it,
|
||||||
|
you can try editing the network's profile directly. The relevant file is at
|
||||||
|
`/etc/NetworkManager/system-connections/UWS.nmconnection`
|
||||||
|
|
||||||
|
This file should look something like below, with relevant information replaced.
|
||||||
|
The file can only be accessed by root
|
||||||
|
|
||||||
|
```
|
||||||
|
[connection]
|
||||||
|
id=UWS
|
||||||
|
uuid=cb62f680-e1da-41c9-bfa0-35e7ef6f5137
|
||||||
|
type=wifi
|
||||||
|
interface-name=wlan0
|
||||||
|
timestamp=1657043376
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
mode=infrastructure
|
||||||
|
ssid=UWS
|
||||||
|
|
||||||
|
[wifi-security]
|
||||||
|
key-mgmt=wpa-eap
|
||||||
|
|
||||||
|
[802-1x]
|
||||||
|
eap=ttls;
|
||||||
|
identity=emiliko
|
||||||
|
password=PutYourPasswordInPlainTextHere_YesPlainText
|
||||||
|
phase2-auth=pap
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=stable-privacy
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, use the file above as a reference to edit it via
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli connection edit UWS
|
||||||
|
```
|
||||||
|
|
||||||
|
## After setting up above
|
||||||
|
```bash
|
||||||
|
nmcli device wifi connect UWS
|
||||||
|
```
|
||||||
|
|
||||||
|
NetworkManager takes a bit, about 30s, to finish authentication. This will also
|
||||||
|
happen during boot, so you can't use the network right away
|
||||||
|
|
||||||
|
If your network does not use PAP authetication, it might just work to type the
|
||||||
|
password in
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli --ask device wifi connect UWS
|
||||||
|
```
|
19
notes/linux/pass.md
Normal file
19
notes/linux/pass.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Pass - The Unix password manager
|
||||||
|
Forget proprietary password managers that require a subscription, use `pass` to
|
||||||
|
generate, store, and retrieve all your passwords through your gpg key
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pass init emiliko@mami2.moe
|
||||||
|
pass insert university/password
|
||||||
|
pass insert -e university/username
|
||||||
|
```
|
||||||
|
|
||||||
|
Passwords, or rather entire files can be retrieved to stdout, the clipboard, or
|
||||||
|
a qrcode. Stdout will show multiline files. `-c` will only copy the first line
|
||||||
|
to `wl-clipboard` for `PASSWORD_STORE_CLIP_TIME` or 45s
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pass [show] university/password
|
||||||
|
pass [show] -c university/password
|
||||||
|
pass [show] -q university/password
|
||||||
|
```
|
26
notes/linux/ramdisks.md
Normal file
26
notes/linux/ramdisks.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Ramdisks
|
||||||
|
Ram is fast and files sometimes need to be quick. Disks via ramfs and tmpfs
|
||||||
|
allow us to mount a file system entirely in the ram, and it's supported by the
|
||||||
|
linux kernel out of the box
|
||||||
|
|
||||||
|
Tmpfs is the newer version of ramfs, with the only difference being that tmpfs
|
||||||
|
has a maximum size that it won't exceed. Ramfs doesn't actually bound its own
|
||||||
|
size, so the system can run out of memory
|
||||||
|
|
||||||
|
# mount -t tmpfs -o uid=1000,size=1g tmpfs /home/emiliko/mnt
|
||||||
|
|
||||||
|
Mounts a temporary file system with a maximum size of 1GB at ~/mnt. Ramdisks
|
||||||
|
only use the size they need, so mounting this blank file system won't take up
|
||||||
|
any ram at first
|
||||||
|
|
||||||
|
Unmounting a ramdisk will clear everything off, which happens every time the
|
||||||
|
system is powered off
|
||||||
|
|
||||||
|
Linux systems come with a `/dev/shm` directory by default, which is a ramdisk
|
||||||
|
accessible by all users. To find the size of a ramdisk use `df -h /dev/shm`. To
|
||||||
|
check which ramdisks are mounted, use `findmnt` or `mount`
|
||||||
|
|
||||||
|
For more information:
|
||||||
|
- `man 8 mount`
|
||||||
|
- `man 5 tmpfs`
|
||||||
|
- [ArchWiki](https://wiki.archlinux.org/title/tmpfs)
|
50
notes/linux/usb_mounting_disks.md
Normal file
50
notes/linux/usb_mounting_disks.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Mounting disks
|
||||||
|
On MacOS, there's `diskutil` which handles everything to do with disks and
|
||||||
|
partitioning all in one. It also has a graphical frontend. Macs by default
|
||||||
|
automatically mount readable external media into `/Volumes` and nothing explicit
|
||||||
|
needs to be done, although `diskutil` can trigger this as well
|
||||||
|
|
||||||
|
In Linux, the functionality of this tool is broken up into `fdisk`, `lsblk`,
|
||||||
|
`df`, `parted`, and `mount`. For querying information, these overlap heavily and
|
||||||
|
can often be used interchangeably. `lsblk` is often sufficient to query external
|
||||||
|
drives, with the following options:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsblkf -o name,label,fstype,mountpoint,size,state
|
||||||
|
```
|
||||||
|
|
||||||
|
However, `mount` is a particularly bad substitute for `diskutil`. For one it
|
||||||
|
needs root privileges for something as simple as mounting a usb stick. It also
|
||||||
|
doesn't create mount pointer for us in `/Volumes`, we have do to that manually
|
||||||
|
|
||||||
|
Instead, it's a good idea to install `udisks2`. "Easier" distros typically come
|
||||||
|
with this or something similar preinstalled. `udisksctl` is much more similar to
|
||||||
|
`diskutil`. It'll mount drives without requiring root into
|
||||||
|
`/run/media/<username>/`, using the EFI label for that partition
|
||||||
|
|
||||||
|
```bash
|
||||||
|
udisksctl help
|
||||||
|
udisksctl mount -b /dev/sda2
|
||||||
|
udisksctl mount -b /dev/sda3
|
||||||
|
```
|
||||||
|
|
||||||
|
You can mount multiple partitions from the same block device at the same time
|
||||||
|
|
||||||
|
Do not try to mix `mount` and `udisksctl`! This can lead to some severe
|
||||||
|
nonsense, like ghost disks. Before using `udisksctl` consider checking the
|
||||||
|
output of `mount`. Note that `lsblk` may know less than `mount` and `df`
|
||||||
|
|
||||||
|
There are no guarantees that an external drive will have any particular name.
|
||||||
|
This is problematic in scripts and requires an `lsblk` every time before
|
||||||
|
mounting external media. Instead you can use the automatically created symlink
|
||||||
|
in `/dev/disk/by-*`. For example, a partition with label `hey_hey` can always be
|
||||||
|
mounted with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
udisksctl mount -b /dev/disk/by-label/hey_hey
|
||||||
|
```
|
||||||
|
|
||||||
|
There can presumably be problems with conflicting partition labels, though it's
|
||||||
|
better not to use `udisksctl` in that case either. `/dev/disk/by-id/*` uses WWID
|
||||||
|
for identification, which is stored on the hardware for the drive and guaranteed
|
||||||
|
to be universally unique. That's a better idea for the fstab file
|
46
notes/linux/veracrypt.md
Normal file
46
notes/linux/veracrypt.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Veracrypt
|
||||||
|
A cross-platform block device encryption program with support for passwords,
|
||||||
|
keys, hidden volumes, and manual PIM setting for security
|
||||||
|
|
||||||
|
Here we use `alias vera='veracrypt -t'` for the non-graphic interface
|
||||||
|
|
||||||
|
AES is the best all-round choice of cipher. Sha256 is the best choice of hash
|
||||||
|
|
||||||
|
Keyfiles must be prepared before locking a volume. `vera --create-keyfile` can
|
||||||
|
create one, or just use a few 100 bytes from /dev/urandom in a file.
|
||||||
|
|
||||||
|
Veracrypt devices must be mounted on a directory and require root access to use
|
||||||
|
`mount`
|
||||||
|
|
||||||
|
Dismount volumes with the `-d` option, providing a path to the mount point, the
|
||||||
|
name of the volume, or nothing to unmount all veracrypt volumes. Sometimes
|
||||||
|
veracrypt may fail to unmount. To check which process is using the container use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
please fuser -vm <mount-point>
|
||||||
|
# For the really desperate
|
||||||
|
lsof
|
||||||
|
# Or if it must be closed no matter what process is using it
|
||||||
|
vera --force --dismount
|
||||||
|
umount -f <mount-point>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating a new volume interactively
|
||||||
|
Start with `vera -c`. The most sensible default are:
|
||||||
|
|
||||||
|
```
|
||||||
|
Volume type: Normal
|
||||||
|
Volume path: /home/emiliko/file_name # Use absolute path!
|
||||||
|
Volume size?
|
||||||
|
Encryption Algorithm: (1) AES
|
||||||
|
Hash algorithm: (1) SHA-512
|
||||||
|
Filesystem: (8) Btrfs
|
||||||
|
```
|
||||||
|
|
||||||
|
## iNode problems
|
||||||
|
If you're making a very small container, you may run into inode issues. Btrfs
|
||||||
|
doesn't use inodes, so it should be ideal. However, btrfs requires a file system
|
||||||
|
over 1M for sure
|
||||||
|
|
||||||
|
Ext4 uses inodes and by default won't have nearly enough on a small drive. For
|
||||||
|
example, the default is 96 inodes for a 1M drive
|
128
notes/macos/apple_bsd.md
Normal file
128
notes/macos/apple_bsd.md
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
# Apple corner
|
||||||
|
MacOS is a BSD derivative that constantly does things differently under the
|
||||||
|
hood. While most things are Unix compatible, some things are just different
|
||||||
|
|
||||||
|
### Basic setup
|
||||||
|
MacOS requires a few manual interventions to get the system working
|
||||||
|
|
||||||
|
# spctl --master-disable
|
||||||
|
Reveals the option in "Security & Privacy" to run apps from any developer
|
||||||
|
|
||||||
|
~/Library/Sounds/madoka_error.aiff
|
||||||
|
Sound files stored in this directory are available under Sound -> Sound Effects
|
||||||
|
|
||||||
|
~/Library/KeyBindings/DefaultKeyBinding.dict
|
||||||
|
Allows basic remapping for system-wide key binds. Use `skhd` for complex hotkeys
|
||||||
|
|
||||||
|
### Basic commands
|
||||||
|
|
||||||
|
$ echo 'hello' | pbcopy
|
||||||
|
$ pbpaste > note.txt
|
||||||
|
Interact with the system clipboard through terminal. This does not work for
|
||||||
|
images. Install `pngpaste` for that functionality
|
||||||
|
|
||||||
|
$ say 'something'
|
||||||
|
Says string with system voice. Useful as a notification for when a task is done
|
||||||
|
|
||||||
|
$ afplay
|
||||||
|
Plays the audio of an audio file, such as an `mp3` or `wav`
|
||||||
|
|
||||||
|
### Disk Utility
|
||||||
|
|
||||||
|
$ diskutil list
|
||||||
|
Lists all the volumes the system currently sees. This works for unmounted and
|
||||||
|
encrypted partitions as well
|
||||||
|
|
||||||
|
$ diskutil mount disk1s1
|
||||||
|
Mounts `disk1s1`. Most useful to mount USB drives without physically reseeding
|
||||||
|
|
||||||
|
$ diskutil apfs unlockVolume disk1s1
|
||||||
|
Unlocks and mounts an apple file system volume
|
||||||
|
|
||||||
|
### Launch daemon
|
||||||
|
Systemd for MacOS. It will automatically load scripts in designated directories
|
||||||
|
on login. It can also be controlled manually through `launchctl`
|
||||||
|
|
||||||
|
$ launchctl load -w ~/Library/LaunchAgents/com.skhd.plist
|
||||||
|
$ launchctl unload -w ~/Library/LaunchAgents/com.skhd.plist
|
||||||
|
Loads and starts the skhd daemon. `<key>Label</key>` must be the same to unload
|
||||||
|
|
||||||
|
# launchctl list | grep skhd
|
||||||
|
Check the status of a running process. First number is the PID, second number is
|
||||||
|
the exit code. If the second number isn't 0 or there's no PID something broke
|
||||||
|
|
||||||
|
/Users/emiliko/Library/LaunchAgents/com.launcher.plist
|
||||||
|
This file will be started automatically on emiliko's login. All paths provided
|
||||||
|
in must be absolute paths from root. Use `/Users/emiliko/` not `~/`
|
||||||
|
|
||||||
|
/Users/emiliko/Library/LaunchAgents/com.launcher.plist
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string>/tmp/skhd.out</string>
|
||||||
|
<key>StandardErrorPath</key>
|
||||||
|
<string>/tmp/skhd.err</string>
|
||||||
|
Redirects stdout and stderr. Watch these files with `tail -f /tmp/skhd.err | nl`
|
||||||
|
|
||||||
|
### Installing SSHFS on Mac
|
||||||
|
To set up ssh filesystem (sshfs) on a mac, follow these steps on the client:
|
||||||
|
|
||||||
|
$ brew install --cask osxfuse
|
||||||
|
Installs `osxfuse`. This is an open source tool to extend your mac's fs support
|
||||||
|
|
||||||
|
https://osxfuse.github.io/
|
||||||
|
$ curl https://github.com/osxfuse/sshfs/releases/download/osxfuse-sshfs-2.5.0/sshfs-2.5.0.pkg
|
||||||
|
Recently brew removed sshfs from its supported casks, since it relies on closed
|
||||||
|
source code. Instead, you'll need to install it directly from the download link
|
||||||
|
|
||||||
|
See ssh_notes for using SSHFS
|
||||||
|
|
||||||
|
### OSA script
|
||||||
|
MacOS's GUI can often be controlled through the use of Apple's `osascript`.
|
||||||
|
Notably, this can allow shell programs to give GUI notifications
|
||||||
|
|
||||||
|
osascript -e 'display notification "'"${message}"'
|
||||||
|
Sends the system notification with the contents of `$message`
|
||||||
|
|
||||||
|
osascript -e 'display notification "'"${msg}"'" with title "Skhd"'
|
||||||
|
Adds a "Skhd" as a title to the notification
|
||||||
|
|
||||||
|
osascript -e 'display notification "'"${msg}"'" with title "Skhd" subtitle
|
||||||
|
"Could not save image"'
|
||||||
|
Further adds a subtitle for the notification
|
||||||
|
|
||||||
|
afplay $(defaults read .GlobalPreferences.plist \
|
||||||
|
| awk '/sound.beep.sound"/ { gsub(/(.*= ")|(";)/, "", $0); print }')
|
||||||
|
Plays the default system error sound through the current audio output device
|
||||||
|
|
||||||
|
|
||||||
|
## FreeBSD corner
|
||||||
|
Keep in mind that MacOS is based on a really old FreeBSD and NetBSD kernel, so
|
||||||
|
many sections here will somewhat apply to Macs as well
|
||||||
|
|
||||||
|
#### Users and groups
|
||||||
|
Various commands for managing system permissions. Many can be, at least
|
||||||
|
somewhat, run the user themselves with their password
|
||||||
|
|
||||||
|
# adduser
|
||||||
|
# rmuser
|
||||||
|
$ chpass # edit user account settings, like login name and expiry
|
||||||
|
$ passwd # change a user's password
|
||||||
|
$ pw # a cli frontend for the settings files above. More advanced
|
||||||
|
https://docs.freebsd.org/en/books/handbook/basics/#users-modifying
|
||||||
|
|
||||||
|
/etc/group
|
||||||
|
$ id emiliko
|
||||||
|
Shows groups a user belongs to. User seems to implicitly belong to their group
|
||||||
|
|
||||||
|
rwxr-x---x .
|
||||||
|
rwxr-x-r-- secret_file
|
||||||
|
rwxr-x-rw- no_touching
|
||||||
|
Oddly, the `x` on the directory here means means all other users:
|
||||||
|
- Can `cd` into the directory
|
||||||
|
- Cannot `ls` in this directory
|
||||||
|
- Can read the file `secret_file` using something like `vim secret_file`
|
||||||
|
- Can write to `no_touching`. Vim can only do this with `:x!` not `:w!`
|
||||||
|
|
||||||
|
# service sshd restart
|
||||||
|
Reboots the ssh daemon. Users connected through ssh won't lose connection, if
|
||||||
|
the reboot is successful
|
||||||
|
[//]: # ex: set ft=markdown:tw=80:
|
21
notes/macos/macos_groups.md
Normal file
21
notes/macos/macos_groups.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Groups in macos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dscl . -create /groups/newgroupname
|
||||||
|
sudo dscl . -append /groups/newgroupname gid 4200
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates a new group. Alternatively use System Preferences -> Users and Groups
|
||||||
|
|
||||||
|
```bash
|
||||||
|
id -Gn emiliko
|
||||||
|
```
|
||||||
|
|
||||||
|
List all the groups `emiliko` belongs to
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chmod -R g=u .
|
||||||
|
```
|
||||||
|
|
||||||
|
Set the group privileges of the file hierarchy rooted at `.` to be the same as
|
||||||
|
the user. Very nice to convert a directory to be editable by ssh users
|
37
notes/macos/macos_qemu.md
Normal file
37
notes/macos/macos_qemu.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Qemu
|
||||||
|
Optimized options that seem to work on MacOS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
-m 4G -smp 6 # Resources: Use 4GB memory and 6 cpus
|
||||||
|
-machine type=q35,accel=hvf # Machine: Default is `pc`. `q35` should be better. Haven't noticed any perfomance gains
|
||||||
|
# Hypervisor: Uses HyperVisorFramework to speed up qemu a LOT, ~6x
|
||||||
|
-drive file=archlinux.qcow2,media=disk,if=virtio # Boot: Points to the image
|
||||||
|
-nic user,hostfwd=tcp::10022-:22 # Network: Forward host port 10022 to guest 22, so `ssh -p10022 user@localhost` should work
|
||||||
|
|
||||||
|
# Display options on MacOS:
|
||||||
|
# If you launch this script in the background, the same terminal can be
|
||||||
|
# used to ssh into qemu. After exiting, tmux's scrollback breaks. Opening
|
||||||
|
# and closing [n]vim fixes this...
|
||||||
|
-nographic
|
||||||
|
# Doesn't do anything noticably different from just -nographic
|
||||||
|
-monitor none -curses -nographic
|
||||||
|
# Support a 4k instance on MacOS. A spice server would be better. It's
|
||||||
|
# really laggy with KDE, to the point of unusable
|
||||||
|
-vga virtio -full-screen -display cocoa
|
||||||
|
# Only supports 1080p. MacOS must use a cocoa display. Compared to above
|
||||||
|
# the display scales by 2x which makes text bigger tho more blurry
|
||||||
|
-vga std -display cocoa
|
||||||
|
```
|
||||||
|
|
||||||
|
# Qemu fully nongraphic
|
||||||
|
|
||||||
|
MacOS can't use `-display ncurses` properly with qemu. Ncurses requires a linux
|
||||||
|
kernel to work properly. Instead use `-nographic` and launch the process in the
|
||||||
|
background. Bash uses `&` for backgrounding. You can now SSH into the qemu
|
||||||
|
instance.
|
||||||
|
|
||||||
|
Bonus:
|
||||||
|
For shared file systems, there are two options on Macs:
|
||||||
|
- MacFUSE - Manually setup and mount with sshfs. It's much easier to use
|
||||||
|
- lima - Tries to do reverse sshfs for you and forwards ports too. This one is
|
||||||
|
pretty new and questionably useful compared to manually using sshfs
|
37
notes/python/ipython_np.md
Normal file
37
notes/python/ipython_np.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
Notes python and IPython
|
||||||
|
|
||||||
|
## Python
|
||||||
|
#### Virtual envs
|
||||||
|
Virtual environments are the `chroot` and `jails` of python. They essentially
|
||||||
|
temporarily append to the path and source locally installed versions of packages
|
||||||
|
|
||||||
|
$ python3 -m venv jail
|
||||||
|
Creates a new python in
|
||||||
|
|
||||||
|
$ source jail/bin/activate
|
||||||
|
$ deactivate
|
||||||
|
Start and stop the venv. The `$PS1` should indicate which one is active
|
||||||
|
|
||||||
|
$ pip install numpy ipython
|
||||||
|
Installs latest versions of packages to the venv. Use `pip` not `pip3` in venvs
|
||||||
|
|
||||||
|
## IPython
|
||||||
|
For a full blown IDE experience in shell, you'll want to use the IPython REPL.
|
||||||
|
Follow the vim ipython setup instructions to use it rStudio style
|
||||||
|
|
||||||
|
#### Magic in scripts
|
||||||
|
>>> from IPython import get_ipython
|
||||||
|
>>> get_ipython().magic('reset -f')
|
||||||
|
Functions exactly like typing `%reset -f` in the IPython interpreter. When
|
||||||
|
sourcing entire files, percent magic syntax won't work
|
||||||
|
|
||||||
|
#### Graphical interface
|
||||||
|
For certain applications, such as plotting graphs, a gui becomes much more
|
||||||
|
capable than a terminal. `matplotlib` can be easily set up to open a
|
||||||
|
live-updating gui window controlled by `ipython`
|
||||||
|
|
||||||
|
>>> get_ipython.magic('pylab')
|
||||||
|
In [01]: %pylab
|
||||||
|
Starts up a gui for plots. It may not open until the first figure is created
|
||||||
|
|
||||||
|
[//]: # ex: set ft=markdown tw=80:
|
64
notes/python/jupyter.md
Normal file
64
notes/python/jupyter.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# Jupyter
|
||||||
|
Despite being one of the most prolific modern languages, python suffers from a
|
||||||
|
dangerous amount of not-invented-here syndrome. Prepare to fight on all fronts
|
||||||
|
while python reinvents the wheels, though makes it square, just since a
|
||||||
|
text-based terminal is too intimidating for new cs students
|
||||||
|
|
||||||
|
Firstly you'll want to install python and all the other required packages:
|
||||||
|
|
||||||
|
```
|
||||||
|
# pacman -S python python-pip
|
||||||
|
# pacman -S jupyter_console python-qtconsole python-ipython-genutils
|
||||||
|
# pacman -S python-pynvim # For neovim only
|
||||||
|
```
|
||||||
|
|
||||||
|
Next you'll want to generate the configs required for Vim to connect with
|
||||||
|
Jupyter. Follow this section of the
|
||||||
|
[readme](https://github.com/jupyter-vim/jupyter-vim#jupyter-configuration).
|
||||||
|
Jupyter does not come with manpages, though it does give useful support by using
|
||||||
|
`-h` for any of its subcommands
|
||||||
|
|
||||||
|
Now we need to make a virtual environment, otherwise pip will pollute package
|
||||||
|
dependencies all over the system. Create a new environment directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 -m venv new_env_dir
|
||||||
|
$ cd new_env_dir
|
||||||
|
$ . bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can install packages with pip, so long as the prompt stays "activated".
|
||||||
|
If you aren't sure, open another pane and reactivate from there
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python -m pip install ipykernel
|
||||||
|
$ python -m pip install numpy matplotlib networkx
|
||||||
|
```
|
||||||
|
|
||||||
|
Trying to use Jupyter now still won't work. Since virtual environments are very
|
||||||
|
thin layer that just modifies some environment variables, Jupyter will still run
|
||||||
|
as if it's being run from a normal shell. We'll need to attach this venv as a
|
||||||
|
separate kernel on the system Jupyter installation. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 -m ipykernel install --user --name=my_kernel_name
|
||||||
|
```
|
||||||
|
|
||||||
|
Now Jupyter should see it. You can use any shell from here on, not just the
|
||||||
|
venv-activated one
|
||||||
|
|
||||||
|
```
|
||||||
|
$ jupyter kernelspec list
|
||||||
|
```
|
||||||
|
|
||||||
|
We can connect to this kernel with an option
|
||||||
|
|
||||||
|
```
|
||||||
|
$ jupyter console --kernel=my_kernel_name
|
||||||
|
```
|
||||||
|
|
||||||
|
Removing the kernel later is easy too
|
||||||
|
|
||||||
|
```
|
||||||
|
$ jupyter kernelspec remove my_kernel_name
|
||||||
|
```
|
33
notes/python/vim_ipython_repl.md
Normal file
33
notes/python/vim_ipython_repl.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# REPL interaction
|
||||||
|
|
||||||
|
Vim can take advantage of read evaluate print loops (REPL) to run code 'cells'.
|
||||||
|
This is similar to the experience in Jupyter notebooks, Colab, and RStudio
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
|
||||||
|
This is for the IPython interpreter. The normal python REPL isn't as easy to use
|
||||||
|
|
||||||
|
```vim
|
||||||
|
Plug 'jpalardy/vim-slime'
|
||||||
|
```
|
||||||
|
|
||||||
|
Necessary for any sort of REPL interaction through vim. Lets vim send text to
|
||||||
|
other terminals or tmux panes
|
||||||
|
|
||||||
|
```vim
|
||||||
|
Plug 'hanschen/vim-ipython-cell'
|
||||||
|
```
|
||||||
|
|
||||||
|
Plugin provides many conveniences for interacting with REPLs, such as one-line
|
||||||
|
execution, highlighted cell delimiters, and navigation between cells
|
||||||
|
|
||||||
|
# Julia
|
||||||
|
|
||||||
|
Use the same setup as the IPython REPL, except modify the evaluation string
|
||||||
|
|
||||||
|
```vim
|
||||||
|
let g:ipython_cell_run_command = 'Base.run(`clear`); include("{filepath}")'
|
||||||
|
let g:ipython_cell_cell_command = 'include_string(Main, clipboard())'
|
||||||
|
```
|
||||||
|
|
||||||
|
Julia equivalents for pasting the clipboard and executing a file
|
8
notes/qemu/installation_qemu.sh
Normal file
8
notes/qemu/installation_qemu.sh
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-m 4G \
|
||||||
|
-boot d \
|
||||||
|
-display cocoa \
|
||||||
|
-machine type=q35,accel=hvf \
|
||||||
|
-smp 2 \
|
||||||
|
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
|
||||||
|
-cdrom /Users/emiliko/documents/safe/arch_vm/archlinux-2021.01.01-x86_64.iso
|
50
notes/qemu/qemu_arch_start.sh
Normal file
50
notes/qemu/qemu_arch_start.sh
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Qemu booting on MacOS
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-m 4G -smp 6 \
|
||||||
|
-nographic \
|
||||||
|
-accel hvf \
|
||||||
|
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
|
||||||
|
-nic user,hostfwd=tcp::10022-:22 &> /dev/null
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
# Above invocation explained
|
||||||
|
-m 4G -smp 6 # Resources: Use 4GB memory and 6 cpus
|
||||||
|
-machine type=q35,accel=hvf # Machine: Default is `pc`. `q35` should be better, tho haven't noticed anything
|
||||||
|
# Hypervisor: Uses HyperVisorFramework to speed up qemu a LOT, ~6x
|
||||||
|
-drive file=archlinux.qcow2,media=disk,if=virtio # Boot: Points to the image
|
||||||
|
-nic user,hostfwd=tcp::10022-:22 # Network: Forward host port 10022 to guest 22, so `ssh -p10022 user@localhost` should work
|
||||||
|
|
||||||
|
|
||||||
|
# Display options:
|
||||||
|
# If you launch this script in the background, the same terminal can be
|
||||||
|
# used to ssh into qemu. After exiting, tmux's scrollback breaks. Opening
|
||||||
|
# and closing [n]vim fixes this...
|
||||||
|
-nographic \
|
||||||
|
# Doesn't do anything noticably different from just -nographic
|
||||||
|
-monitor none -curses -nographic \
|
||||||
|
# Support a 4k instance on MacOS. A spice server would be better. It's
|
||||||
|
# really laggy with KDE, to the point of unusable
|
||||||
|
-vga virtio -full-screen -display cocoa \
|
||||||
|
# Only supports 1080p. MacOS must use a cocoa display. Compared to above
|
||||||
|
# the display scales by 2x which makes text bigger tho more blurry
|
||||||
|
-vga std -display cocoa \
|
||||||
|
|
||||||
|
|
||||||
|
# Previously used presets:
|
||||||
|
-monitor none \
|
||||||
|
-vga virtio -full-screen -display cocoa \ # 4k supported, though it's really slow at 4k
|
||||||
|
-vga std \ # Normal run, only supports up to 1080p
|
||||||
|
-accel hvf \
|
||||||
|
# possible
|
||||||
|
-vga virto \
|
||||||
|
-enable-kvm \
|
||||||
|
#
|
||||||
|
-net tap,script=/Users/emiliko/documents/safe/arch_vm/tap-up,downscript=/Users/emiliko/documents/safe/arch_vm/tap-down
|
||||||
|
-nographic \
|
||||||
|
-chardev stdio,id=char0 \
|
||||||
|
-serial chardev:char0 \
|
||||||
|
-monitor none \
|
||||||
|
-net nic,model=virtio,macaddr=54:54:00:55:55:55 \
|
||||||
|
|
||||||
|
|
14
notes/qemu/qemu_start.sh
Normal file
14
notes/qemu/qemu_start.sh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-m 4G \
|
||||||
|
-smp 6 \
|
||||||
|
-boot d \
|
||||||
|
-display cocoa \
|
||||||
|
-vga std \
|
||||||
|
-serial stdio \
|
||||||
|
-machine type=q35,accel=hvf \
|
||||||
|
-drive file=archlinux-2021.01.01.qcow2,media=disk,if=virtio \
|
||||||
|
-nic user,hostfwd=tcp::10022-:22
|
||||||
|
#-net tap,script=/Users/emiliko/documents/safe/arch_vm/tap-up,downscript=/Users/emiliko/documents/safe/arch_vm/tap-down
|
||||||
|
#-net nic,model=virtio,macaddr=54:54:00:55:55:55 \
|
||||||
|
|
||||||
|
|
27
notes/shell/chrontab.md
Normal file
27
notes/shell/chrontab.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Crontab
|
||||||
|
Run programs at a given time. Useful for system cleanups and updates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit your crontab file
|
||||||
|
|
||||||
|
Syntax looks like (min, hour, day, month, year). Note these are absolute values,
|
||||||
|
so putting something like `* 1 * * *` will run the program at `1:00am` every
|
||||||
|
day. To understand these times use [this](https://crontab.guru/) Example crontab
|
||||||
|
file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PATH=/usr/local/bin:/bin:/usr/bin
|
||||||
|
HOME=/home/emiliko
|
||||||
|
|
||||||
|
* * * * * ~/program_1.sh # Every minute, on the minute
|
||||||
|
* * * * * (sleep 30; ~/program_1.sh) # Every minute at 30s in
|
||||||
|
1 * * * * ~/program_2.sh # Every hour at :01 minute
|
||||||
|
1 * 3 * * ~/program_3.sh # Every day at 3:01am
|
||||||
|
```
|
||||||
|
|
||||||
|
Since crontab doesn't support resolutions greater than 1 minute, a workaround
|
||||||
|
with `sleep` can be used instead. `program_1.sh` above effectively runs every
|
||||||
|
30s
|
19
notes/shell/ffmpeg_subtitle_extraction.md
Normal file
19
notes/shell/ffmpeg_subtitle_extraction.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Extract subtitles with ffmpeg
|
||||||
|
|
||||||
|
```
|
||||||
|
ffmpeg -i Movie.mkv -map 0:s:0 subs.srt
|
||||||
|
```
|
||||||
|
|
||||||
|
Extract subtitles from the mkv file. This one extracts the 0th subtitle track.
|
||||||
|
To extract the first, use `-map 0:s:1`
|
||||||
|
|
||||||
|
```
|
||||||
|
ffmpeg -ss 10 -t 10 Movie.mkv audio.mp3
|
||||||
|
```
|
||||||
|
|
||||||
|
Another curious thing is [ffmpeg's treatment of arguments](ffmpeg relative). All arguments that
|
||||||
|
come before a file are applied to that file only. The remainder of the command
|
||||||
|
is relative to those inital args. This means seeking forward 10s then cutting
|
||||||
|
10s will actually cut out the 10-20s interval
|
||||||
|
|
||||||
|
[ffmpeg relative]: https://stackoverflow.com/questions/46508055/using-ffmpeg-to-cut-audio-from-to-position
|
52
notes/shell/fifo.md
Normal file
52
notes/shell/fifo.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# Shell pipes and fifo
|
||||||
|
Most bash "blocks" accept a redirection parameter at the end of their
|
||||||
|
declaration. This can replace where the output and errors are going
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn () {
|
||||||
|
echo "error" >&3
|
||||||
|
} 3>&2 2>file
|
||||||
|
# Prints "error" to the standard error. The real stderr is stored in ./file
|
||||||
|
```
|
||||||
|
|
||||||
|
- Functions, as above
|
||||||
|
- Sub-shells: `(echo "one"; echo "two") > file`
|
||||||
|
- Loops: `while (1); do echo "loop"; done > file`
|
||||||
|
|
||||||
|
Remember that redirection syntax looks like `[fd][< | >][&fd | file_path]`,
|
||||||
|
where `fd` is the index in the process' file descriptors. This works for `<` as
|
||||||
|
well. `|&` is identical to using `2>&1 |`
|
||||||
|
|
||||||
|
The order of IO redirection matters. Redirection will go to wherever the
|
||||||
|
redirected destination currently goes. Redeclaring a redirection doesn't work
|
||||||
|
|
||||||
|
```
|
||||||
|
┌3 writes to stdout
|
||||||
|
│ ┌stdout writes to stderr
|
||||||
|
│ │ ┌stderr writes to where 3 writes, so stdout
|
||||||
|
│ │ │
|
||||||
|
echo "one" 3>&1 1>&2 2>&3
|
||||||
|
```
|
||||||
|
|
||||||
|
To do this for the entire shell or script, use `exec`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
exec 4>&1 # Holds onto reference to stdout
|
||||||
|
exec 1>/dev/null # Silences stdout and loses track of it
|
||||||
|
exec 1>&4 4>&1 # Restore stdout through reference in 4 and close 4
|
||||||
|
# Everything back to normal
|
||||||
|
```
|
||||||
|
|
||||||
|
`mkfifo` creates a named pipe, which can be easier to interact with between
|
||||||
|
scripts. Make sure it's being held open at use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkfifo fifo
|
||||||
|
cat fifo >ofif & # Holds open fifo pipe and copies anything in there to ofif
|
||||||
|
exec 3>fifo # fd 3 reffers to pipe fifo
|
||||||
|
echo "double" >&3 # Writes to fifo. >fifo would close the pipe right after
|
||||||
|
exec 3>&- # Manually close the open pipe
|
||||||
|
```
|
||||||
|
|
||||||
|
The example above works similar to `tee` in logging everything in the pipe
|
||||||
|
|
26
notes/shell/fzf_completion.md
Normal file
26
notes/shell/fzf_completion.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Using fzf correctly
|
||||||
|
|
||||||
|
```
|
||||||
|
^r Pull command out of bash history
|
||||||
|
^t Complete file names relative to cwd
|
||||||
|
```
|
||||||
|
|
||||||
|
Standard shortcuts
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mv **<TAB>
|
||||||
|
mv ./**<TAB>
|
||||||
|
```
|
||||||
|
|
||||||
|
When tabbing after `**`, fzf will complete the path. This works with other
|
||||||
|
destinations like `~/Downloads/**<TAB>`
|
||||||
|
|
||||||
|
Fzf also automatically completes most common commands, like `ssh`, `kill`, and
|
||||||
|
`unset`. Note that most of these still require `**`, they just complete what's
|
||||||
|
expected instead of file paths
|
||||||
|
|
||||||
|
You can set up additional completions in a bash config file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
_fzf_setup_completion path mpv
|
||||||
|
```
|
206
notes/shell/git_notes.md
Normal file
206
notes/shell/git_notes.md
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
## Quick start
|
||||||
|
Git is an indispensable tool for code development, though in reality you'll only
|
||||||
|
use a few commands on a day to day basis. This section provides a quick overview
|
||||||
|
of those commands
|
||||||
|
```
|
||||||
|
$ git fetch
|
||||||
|
$ git status -s
|
||||||
|
$ git diff file_1
|
||||||
|
$ git add some_dir
|
||||||
|
$ git commit -m "Changed some directory"
|
||||||
|
$ git switch -c new_branch
|
||||||
|
$ git restore file_2
|
||||||
|
$ git commit -a
|
||||||
|
$ git log --graph --all --oneline --decorate | less
|
||||||
|
$ git push
|
||||||
|
```
|
||||||
|
The above represent ~90% of git commands you'll use. For some of these, like the
|
||||||
|
`git log` command, you should setup aliases
|
||||||
|
|
||||||
|
#### Manual pages
|
||||||
|
$ man gittutorial
|
||||||
|
$ man giteveryday
|
||||||
|
Some useful manual pages for referencing non-specifics
|
||||||
|
|
||||||
|
$ man git-rebase
|
||||||
|
$ git help rebase
|
||||||
|
$ tldr git rebase
|
||||||
|
For information on a single command, add a hyphen to separate out the
|
||||||
|
subcommand. If using `tldr` type the command as you normally would
|
||||||
|
|
||||||
|
#### Referencing commits
|
||||||
|
While most git commands default to `HEAD` without a commit passed, they often
|
||||||
|
accept other commits to operate on. Some commands also need another commit to
|
||||||
|
operate, like `git merge`
|
||||||
|
|
||||||
|
$ git show HEAD # References the current HEAD
|
||||||
|
$ git show HEAD^ # References one commit above the HEAD
|
||||||
|
$ git show HEAD^^ # Two commits above HEAD
|
||||||
|
$ git show HEAD~4 # 4 commits above HEAD
|
||||||
|
$ git show a22a398 # Commit starting with SHA1 a22a398
|
||||||
|
$ git show v0.2.0 # Commit tagged with v0.2.0
|
||||||
|
$ git show master # Tip of the master branch
|
||||||
|
$ git show origin/dev # Tip of the local copy of the origin's dev branch
|
||||||
|
Various examples of referencing commits. These can be mixed together for more
|
||||||
|
complicated referencing, though that's not too common
|
||||||
|
|
||||||
|
$ git show HEAD~4.. # All commits from 4 commits before to HEAD
|
||||||
|
$ git show v2.0..HEAD^ # Commits from tag v2.0 to one before HEAD
|
||||||
|
Some commands accept ranges of references. As expected, if one end of the range
|
||||||
|
is missing, it'll use a default upper/lower bound
|
||||||
|
|
||||||
|
$ git merge origin/master^
|
||||||
|
Merges one before the tip of the local copy of the origin's, possibly outdated,
|
||||||
|
master branch to the current branch. Very useful when working offline
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
#### New projects
|
||||||
|
$ git init
|
||||||
|
Create a new git repository in the current directory with a master branch
|
||||||
|
|
||||||
|
$ git remote add origin git@github.com:Aizuko/configs.git
|
||||||
|
$ git remote add origin ssh://git@github.com:22/Aizuko/configs.git
|
||||||
|
Sets up a remote origin on GitHub. This example uses ssh to connect, though
|
||||||
|
often http will also be supported. The second example specifies port 22
|
||||||
|
|
||||||
|
$ git push --set-upstream origin master
|
||||||
|
Pushes the master branch to the remote origin
|
||||||
|
|
||||||
|
#### Using a previous project
|
||||||
|
$ git clone ssh://git@github.com/Aizuko/configs.git
|
||||||
|
$ git clone https://github.com/Aizuko/configs.git
|
||||||
|
Clone a git repository from a remote. Everything will automatically be setup
|
||||||
|
|
||||||
|
$ git clone -b dev --single-branch --depth=1 ssh://git@github.com:22/Aizuko/configs.git
|
||||||
|
Clone the tip of the dev branch. Useful for saving storage, if you only need the
|
||||||
|
latest commit
|
||||||
|
|
||||||
|
.git/config
|
||||||
|
[remote "origin"]
|
||||||
|
- fetch = +refs/heads/dev:refs/remotes/origin/dev
|
||||||
|
+ fetch = +refs/heads/*:refs/remotes/origin/*
|
||||||
|
Sets git to synchronize all branches from origin, instead of just `dev`
|
||||||
|
|
||||||
|
$ git remote -v
|
||||||
|
List the remotes for this repository. Often useful if you want to change the
|
||||||
|
connection protocol
|
||||||
|
|
||||||
|
$ git remote set-url origin git@github.com:Aizuko/configs.git
|
||||||
|
Changes a remote. You'll rarely use this outside of changing protocols
|
||||||
|
|
||||||
|
$ git clone --depth=1 git://github.com/Aizuko/configs.git
|
||||||
|
Quick way to clone a Github repository without needing to login
|
||||||
|
|
||||||
|
$ git remote add upstream git@github.com:22/Aizuko/configs.git
|
||||||
|
Sets up another remote to track. Particularly important with forked branches
|
||||||
|
|
||||||
|
## Branches
|
||||||
|
Branches are a way to organize workflow into separate goals. This allows commits
|
||||||
|
for a feature that is still in development. Git recommends making a lot of cheap
|
||||||
|
branches and deleting them once merged
|
||||||
|
|
||||||
|
$ git branch -a
|
||||||
|
Lists all the branches on the local system
|
||||||
|
|
||||||
|
#### Git checkout changes
|
||||||
|
`git checkout` was one of the most common commands to run in git, since it
|
||||||
|
handled way too much. Starting in git 2.23 the command has been split into two
|
||||||
|
new commands. `switch` deals with branches while `restore` resets files
|
||||||
|
|
||||||
|
$ git restore file.txt
|
||||||
|
$ git checkout file.txt
|
||||||
|
Restore a file to how it was in the `HEAD's` commit
|
||||||
|
|
||||||
|
$ git restore --source HEAD^ file.txt
|
||||||
|
$ git checkout HEAD^ file.txt
|
||||||
|
Restore the file to match the commit one before the `HEAD`
|
||||||
|
|
||||||
|
$ git switch master
|
||||||
|
$ git checkout master
|
||||||
|
Switch to the `master` branch
|
||||||
|
|
||||||
|
$ git switch -c dev
|
||||||
|
$ git checkout -b dev
|
||||||
|
Create a new branch called `dev`
|
||||||
|
|
||||||
|
#### Removing branches
|
||||||
|
Once a branch's goal has been achieved and merged, there's no use in keeping it
|
||||||
|
around. Having a bunch of old branches is simply confusing
|
||||||
|
|
||||||
|
$ git branch --merged
|
||||||
|
Shows which branches have been merged. Many of these are often safe to delete
|
||||||
|
|
||||||
|
$ git branch -d merged_branch
|
||||||
|
Deletes a branch locally. Only deletes branches that have been fully merged into
|
||||||
|
an upstream, so often the remote. There's no fear in losing commits this way
|
||||||
|
|
||||||
|
$ git branch -D deadend_branch
|
||||||
|
$ git branch -f -d deadend_branch
|
||||||
|
Force deletes a local branch, regardless of whether it's been merged. You can,
|
||||||
|
and likely will, lose commits this way. This should only be used for local
|
||||||
|
experimental branches that quickly hit a dead end in development
|
||||||
|
|
||||||
|
$ git push origin --delete merged_branch
|
||||||
|
Deletes the branch on the remote repository as well
|
||||||
|
|
||||||
|
#### Tagging
|
||||||
|
Tags can be added to make referencing certain commits easier. Tags can often be
|
||||||
|
used instead of the rather complicated SHA1 to reference commits
|
||||||
|
|
||||||
|
$ git tag -a v0.1.0 a22a398
|
||||||
|
$ git tag -a v0.1.0 a22a398 -m "First version"
|
||||||
|
Creates an annotated tag for the commit `a22a398`. The tag will be automatically
|
||||||
|
signed
|
||||||
|
|
||||||
|
$ git tag -a -f v0.2.0 a22a398 -m "Add compact statusline"
|
||||||
|
Overwrite previous tag for a commit with a new tag. This isn't a problem for
|
||||||
|
tags that are only local to the system. Do not attempt for remote tags
|
||||||
|
|
||||||
|
$ git push origin v0.1.0
|
||||||
|
$ git push origin --tags v0.1.0 v0.2.0
|
||||||
|
Push up locally created tags to the remote. Tags need to be explicitly pushed.
|
||||||
|
Note that undoing tag pushes is really hard and shouldn't be done
|
||||||
|
|
||||||
|
## Ignoring files
|
||||||
|
In general there are 2 types of files you won't want to track with git: build
|
||||||
|
artifacts and files specific to your computer. Stopping git from tracking these
|
||||||
|
is done through git ignore pattern files
|
||||||
|
|
||||||
|
./.gitignore
|
||||||
|
Sits in the root of a git repository as a local ignore file. This will be
|
||||||
|
committed to the repository, so other users will ignore the same files
|
||||||
|
|
||||||
|
./.git/info/exclude
|
||||||
|
Acts like a `.gitignore` file specific to your system's repository. It will not
|
||||||
|
be committed. Useful for random files you have lying around
|
||||||
|
|
||||||
|
~/.gitignore_global
|
||||||
|
A `gitignore` that applies to every repository for the user. It will not be
|
||||||
|
committed to any particular repository, so it's more similar to a git exclude
|
||||||
|
file. It doesn't need any particular name, just source it in `~/.gitconfig`:
|
||||||
|
```
|
||||||
|
[core]
|
||||||
|
excludesfile = ~/.gitignore_global
|
||||||
|
```
|
||||||
|
|
||||||
|
`.gitignore` files use pattern matching similar to regex
|
||||||
|
|
||||||
|
target
|
||||||
|
target/**/*
|
||||||
|
Ignores anything in and including the `./target` directory
|
||||||
|
|
||||||
|
target/notes_[0-9].md
|
||||||
|
target/notes_?.md
|
||||||
|
Doesn't track any note files from 0-9, though will track anything higher, such
|
||||||
|
as `target/notes_12.md`. A `?` matches any one character, in this case also
|
||||||
|
matching `target/notes_a.md`
|
||||||
|
|
||||||
|
!target/*_notes_*/lec_*.md
|
||||||
|
Track any lecture file in any notes directory in `target`. This can match paths
|
||||||
|
like `target/cmput_notes_1/lec_2.md` and `target/japan_notes_12/lec_passive.md`
|
||||||
|
|
||||||
|
$ git rm --cached file.txt
|
||||||
|
In shell, removes a currently tracked file from tracking. This won't remove the
|
||||||
|
file from your system. Useful when you start ignoring a previously tracked file
|
||||||
|
|
||||||
|
[//]: # ex: set ft=markdown:tw=80:
|
32
notes/shell/jq_json_query_parser.md
Normal file
32
notes/shell/jq_json_query_parser.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# JQ, stream json parser
|
||||||
|
|
||||||
|
`jq` is a minimal json parser that's pretty useful in shell scripts. It can
|
||||||
|
quickly filter json outputs for reading something. Most languages, for example
|
||||||
|
js, have much faster json-parsers built-in, so it's better to use those when
|
||||||
|
possible
|
||||||
|
|
||||||
|
Json output usually comes in one of two forms, either a single json object, or
|
||||||
|
an array of jsons. To extract jsons we can use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yabai -m query --windows --window | jq '.' # Already a single json
|
||||||
|
yabai -m query --windows | jq '.[]' # Iterates through array
|
||||||
|
```
|
||||||
|
|
||||||
|
`jq` takes in a filter on the right side, after a pipe-like separator. The
|
||||||
|
output will just be the that value for single fields
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yabai -m query --windows | jq '.[] | .id' # Id of every window
|
||||||
|
yabai -m query --windows | jq '.[] | .id, .app' # ID and name
|
||||||
|
yabai -m query --windows | jq '.[] | .frame.x' # x field in frame field
|
||||||
|
```
|
||||||
|
|
||||||
|
Your output can be either raw values, json objects, or arrays:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yabai -m query --windows | jq '.[] | .id' # Raw id
|
||||||
|
yabai -m query --windows | jq '.[] | { id: .id }' # Id objects
|
||||||
|
yabai -m query --windows | jq '.[] | [{ id: .id }]' # Id objects in individual arrays
|
||||||
|
yabai -m query --windows | jq '[.[] | { id: .id }]' # Id objects in one array
|
||||||
|
```
|
134
notes/shell/ssh_notes.md
Normal file
134
notes/shell/ssh_notes.md
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
# SSH
|
||||||
|
OpenSSH (ssh) is a secure protocol for connecting to computers/servers remotely.
|
||||||
|
Its uses are infinite, from connecting to clouds to making your laptop a desktop
|
||||||
|
|
||||||
|
### Basics
|
||||||
|
$ ssh -p 10022 emiliko@192.168.0.12
|
||||||
|
$ ssh -p 10022 emiliko@localhost
|
||||||
|
Connects to user `emiliko` on host address `localhost` via port `10022`. Port
|
||||||
|
`22` is the default for ssh
|
||||||
|
|
||||||
|
$ ssh emiliko@68.185.68.169
|
||||||
|
To connect over WAN, there're some additional setup on the server-side:
|
||||||
|
1. Set your IPv4 address manually. This usually requires setting manual DNS
|
||||||
|
servers. `1.1.1.1` and `1.0.0.1` are a good choice
|
||||||
|
2. Set up port forwarding for port 22 on the router to your manual local IPv4
|
||||||
|
3. Find your router's public IP address and use that as the host address
|
||||||
|
|
||||||
|
$ dig +short myip.opendns.com @resolver1.opendns.com
|
||||||
|
$ host myip.opendns.com resolver1.opendns.com
|
||||||
|
$ curl --silent https://ifconfig.me/ip
|
||||||
|
Finds your network's public IP address. This'll the server's be the host address
|
||||||
|
|
||||||
|
### Setting up ssh and ssh keys
|
||||||
|
# pacman -S openssh
|
||||||
|
Update or install ssh. It's often packaged as `openssh` and installs `ssh`
|
||||||
|
|
||||||
|
# systemctl enable sshd
|
||||||
|
Starts up the ssh daemon. The system should now be able to accept ssh
|
||||||
|
connections. On macOS, use Preferences -> Sharing -> Remote Login
|
||||||
|
|
||||||
|
$ ssh-keygen -t ed25519
|
||||||
|
$ ssh-keygen -t ed25519 -f ~/.ssh/arch_qemu_ed25519 -C "For arch qemu"
|
||||||
|
Generate a `ed25519` key pair. Interactively or through flags, this will add a
|
||||||
|
comment at the end of the public key and save it in the designated file
|
||||||
|
|
||||||
|
$ ssh-copy-id -i ~/.ssh/key_file.pub emiliko@localhost
|
||||||
|
$ cat ~/.ssh/key_file.pub | ssh emiliko@localhost "mkdir -p ~/.ssh && cat >>
|
||||||
|
~/.ssh/authorized_keys"
|
||||||
|
Copy an ssh key to the host. Either one will give you the power of ssh keys
|
||||||
|
|
||||||
|
$ ssh-keygen -pf ~/.ssh/key_file
|
||||||
|
Change the passphrase on the key
|
||||||
|
|
||||||
|
### Using ssh keys
|
||||||
|
$ ssh -i ~/.ssh/identify_file emiliko@localhost
|
||||||
|
Login to user using the identity file. This points to your private key. If the
|
||||||
|
file is secured by a passphrase, you'll need to retype it every time
|
||||||
|
|
||||||
|
$ eval $(ssh-agent) && ssh-add ~/.ssh/key_file.pub
|
||||||
|
Start the ssh agent and add a key file to it. This uses the path of the public
|
||||||
|
key file. The agent prevents the need to retype the passphrase on this terminal
|
||||||
|
|
||||||
|
$ ssh -A emiliko@localhost
|
||||||
|
Forwards the ssh agent to the destination system. Only useful if you plan to ssh
|
||||||
|
from that system
|
||||||
|
|
||||||
|
$ scp -P 10022 ~/file emiliko@localhost:~/dir/
|
||||||
|
Copies file between systems. `cp` except across systems. This uses the same
|
||||||
|
login methods, key or password, as `ssh`. Port option must be capitalized
|
||||||
|
|
||||||
|
$ scp ~/file alias:~/dir/
|
||||||
|
Copies file between systems, using `alias` from `~/.ssh/config` as the
|
||||||
|
destination system. This will automatically specify a user, identity key, etc...
|
||||||
|
|
||||||
|
$ ssh -L 2222:localhost:3333 emiliko@192.168.0.12
|
||||||
|
Creates an ssh tunnel connecting localhost:3333 on the host server to port 2222
|
||||||
|
on the client. Useful for webpages and IDE notebooks
|
||||||
|
|
||||||
|
### SSH keys with git
|
||||||
|
After setting up ssh keys in both GitHub and your computer, you'll need to
|
||||||
|
change repositories to use ssh instead of the http protocol
|
||||||
|
|
||||||
|
$ git remote -v
|
||||||
|
Echos a list of remote sources for the current repository. If the URLs start
|
||||||
|
with `http`, ssh protocol is not being used to connect to the remote sources
|
||||||
|
|
||||||
|
$ git remote add origin git@github.com:Aizuko/configs.git
|
||||||
|
$ git remote set-url origin ssh://git@github.com:22/Aizuko/configs.git
|
||||||
|
Use ssh protocol when connecting to remote origin. `add` is for new projects
|
||||||
|
which don't have an origin yet. `set-url` is for existing projects using http
|
||||||
|
|
||||||
|
### Mounting remote filesystems with SSHFS
|
||||||
|
SSH can mount a remote file system as if it's a laggy disk connected to your
|
||||||
|
system. This can be a nice way to locally view and edit remote files
|
||||||
|
|
||||||
|
Disclaimer: These commands have only been tested on MacOS using macFUSE
|
||||||
|
|
||||||
|
$ mount
|
||||||
|
Lists all the current mount points
|
||||||
|
|
||||||
|
$ mkdir ~/mnt
|
||||||
|
$ sshfs emiliko@192.168.0.12:/Users/emiliko ~/mnt
|
||||||
|
$ sshfs emi:/Users/emiliko ~/mnt
|
||||||
|
Mounts the Emiliko's home directory to `~/mnt`. Do not try `emi:~/` as bash
|
||||||
|
tilde will expand relative to the host. Specify the remote path from the root
|
||||||
|
|
||||||
|
$ umount emiliko@192.168.0.12:/Users/emiliko
|
||||||
|
$ umount !sshfs:1
|
||||||
|
Unmount the remote filesystem. Remember to type out the full remote path
|
||||||
|
|
||||||
|
$ sshfs -o cache=no emi:/home/emiliko ~/mnt
|
||||||
|
$ umount !sshfs:3
|
||||||
|
Disable caching to reconnect on every command. Prevents false directory listings
|
||||||
|
|
||||||
|
$ pgrep -lf sshfs
|
||||||
|
$ ps aux | grep -i sshfs
|
||||||
|
$ kill -9 10364
|
||||||
|
# umount -f ~/mnt
|
||||||
|
Forcefully unmount the filesystem
|
||||||
|
|
||||||
|
#### SSH Forwarding
|
||||||
|
$ ssh -p10011 -NL 7000:localhost:8080 emiliko@localhost &
|
||||||
|
$ ssh -NL 7000:localhost:8080 emi &
|
||||||
|
Opens an ssh tunnel between `7000` on the client and `localhost:8080` on the
|
||||||
|
server. Best used with `&`, as in line 2, to avoid obstructing the current pane
|
||||||
|
|
||||||
|
#### SSH config
|
||||||
|
~/.ssh/config
|
||||||
|
Host paraarch
|
||||||
|
User emiliko
|
||||||
|
Hostname 192.168.0.12
|
||||||
|
Port 22
|
||||||
|
IdentityFile ~/.ssh/parallels_arch_ed25519
|
||||||
|
IdentitiesOnly=yes
|
||||||
|
Adds a new host `paraarch` to the ssh config. `paraarch` can be used instead of
|
||||||
|
the host name and it will automatically specify these flags. `IdentitiesOnly`
|
||||||
|
resolves some issues relating to multiple failed connection attempts
|
||||||
|
|
||||||
|
~/.ssh/config
|
||||||
|
Host github.com
|
||||||
|
Hostname github.com
|
||||||
|
IdentityFile ~/.ssh/github_key_ed25519
|
||||||
|
When pulling from remote origin `git@github.com`, this key will be used
|
||||||
|
[//]: # ex: set ft=markdown:tw=80:
|
5
notes/shell/ssh_port_forwarding.md
Normal file
5
notes/shell/ssh_port_forwarding.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# SSH port forwarding
|
||||||
|
ssh -p10011 -NL 7000:localhost:8080 emiliko@localhost &
|
||||||
|
Opens an ssh tunnel without obstructing the current terminal. Syntax for the
|
||||||
|
tunnel looks like:
|
||||||
|
<client_port>:<url_from_host:host_port>
|
406
notes/shell/unix_bash.md
Normal file
406
notes/shell/unix_bash.md
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
# Bash
|
||||||
|
###### Process priority
|
||||||
|
Since the processor must decide priority, it uses a scale from -20 through 20 to
|
||||||
|
rank what has priority, with -20 being the highest priority. By default,
|
||||||
|
processes launched by the user start with a niceness of 0
|
||||||
|
|
||||||
|
# nice --10 ./start_qemu.sh
|
||||||
|
# nice -n -10 ./start_qemu.sh
|
||||||
|
Starts the process, in this case `start_qemu.sh`, with a given niceness level,
|
||||||
|
in this case `-10`. The `-n` option increments from the base value, usually 0
|
||||||
|
|
||||||
|
# renice -2 1244
|
||||||
|
# renice -n -2 1244
|
||||||
|
Changes the niceness of a running process via process id, in this case 1244.
|
||||||
|
`-n` increments niceness from the current value, in this case by `-2`
|
||||||
|
|
||||||
|
$ ps -fl -C 1244
|
||||||
|
Check the niceness of process with id 1244
|
||||||
|
|
||||||
|
###### Job Control in Bash
|
||||||
|
You should not use jobs if you can help it! Especially when it comes to
|
||||||
|
input/output jobs are terribly unclear. Only use them for tasks that will never
|
||||||
|
ask for input or give an output. Use a multiplexer (`tmux`) instead
|
||||||
|
|
||||||
|
$ python -m SimpleHTTPServer 3000 &
|
||||||
|
Starts a process, in this case the python server, in the background. Just append
|
||||||
|
a `&` at the end
|
||||||
|
|
||||||
|
*Oh no, I didn't launch the process in the background*
|
||||||
|
^z
|
||||||
|
If you want to move suspend the current process, `^z` will suspend and stop it
|
||||||
|
|
||||||
|
$ bg %2
|
||||||
|
$ bg 2
|
||||||
|
$ %2 &
|
||||||
|
Continues the stopped job in the background. In this case, we use job identifier
|
||||||
|
1, which will start that specific job. You can omit the `%` with `bg`
|
||||||
|
|
||||||
|
$ fg %2
|
||||||
|
Bring a job back to the foreground. Uses identifiers much like `bg`
|
||||||
|
|
||||||
|
$ jobs -l
|
||||||
|
List all background jobs running. `-l` shows their process id
|
||||||
|
|
||||||
|
$ kill %2
|
||||||
|
Kills a background job, via identifiers. The `%` is not optional here!
|
||||||
|
|
||||||
|
$ wait %2
|
||||||
|
Waits for job identifier `2` to finish. Passing no arguments waits for all
|
||||||
|
background jobs
|
||||||
|
|
||||||
|
$ wlsunset -t 4000 -T 65000 -g 0.9 &
|
||||||
|
$ disown %1
|
||||||
|
Launches `wlsunset` in the background. Then, assuming it's job 1 under `jobs`,
|
||||||
|
disowns the process. The shell can now close with the process still running
|
||||||
|
|
||||||
|
$ wlsunset -t 4000 -T 65000 -g 0.9 & disown
|
||||||
|
Same as above. More compact
|
||||||
|
|
||||||
|
$ { wlsunset -t 4000 -T 65000 -g 0.9 & } &
|
||||||
|
$ ( wlsunset -t 4000 -T 65000 -g 0.9 & ) &
|
||||||
|
Same as above, background and disowns the subshell. `{}` execute the subshell in
|
||||||
|
the current shell's context, while `()` start a fresh shell. `{}` are also used
|
||||||
|
in brace expansion, so they need to be delimited by spaces
|
||||||
|
|
||||||
|
|
||||||
|
###### Vim editing for Bash
|
||||||
|
$ set -o vi
|
||||||
|
Makes bash use vi key binds. Note, this uses `vi` not `vim` bindings. Generally
|
||||||
|
this isn't recommended, even for complete vim users
|
||||||
|
|
||||||
|
$ export EDITOR='vim'
|
||||||
|
Bash will run the specified command when looking for an editor
|
||||||
|
|
||||||
|
<C-x><C-r>
|
||||||
|
Open current shell line in editor. Really powerful for long lines
|
||||||
|
|
||||||
|
See the (Ex section)[#Batch-editing-with-ex] for batch editing with vim
|
||||||
|
in `ex` mode
|
||||||
|
|
||||||
|
###### Stop yourself from deleting files
|
||||||
|
$ chmod a-w safe_directory
|
||||||
|
Prevents writing to the directory. Writing, in the sense of editing files is
|
||||||
|
still controlled by file permissions, you just can't remove or make new ones
|
||||||
|
|
||||||
|
# chown other_user safe_directory; chmod 755 safe_directory
|
||||||
|
Makes another user own the directory. All others uses cannot make/remove files.
|
||||||
|
Same as above, if ownership is given to root, though a bit more explicit
|
||||||
|
|
||||||
|
# touch safe_directory/file
|
||||||
|
# rm safe_directory/file
|
||||||
|
You can still create and delete files in this directory with root
|
||||||
|
|
||||||
|
###### Reusing commands
|
||||||
|
See HISTORY EXPANSION in `man bash` for more information
|
||||||
|
|
||||||
|
$ sudo !!
|
||||||
|
$ sudo !-1
|
||||||
|
Recalls the last command and runs it as root. Notice the `-1` can be any number
|
||||||
|
to recall older commands
|
||||||
|
|
||||||
|
$ !man
|
||||||
|
Rerun the last command starting with the string `man`
|
||||||
|
|
||||||
|
$ !?diff?:p
|
||||||
|
Print the last command that contained the string `diff`
|
||||||
|
|
||||||
|
$ mv !:2 ../!:2
|
||||||
|
Substitutes `!:2` with the second argument of the previous command. The command
|
||||||
|
itself is `!:0`, so it's the second argument. Here it moves a directory up
|
||||||
|
|
||||||
|
$ mv !^ !^'_name'
|
||||||
|
$ mv !$ !$'_name'
|
||||||
|
`$` and `^` are aliases for the first and last arguments. Here it changes a file
|
||||||
|
or directory name by adding `_name` at the end
|
||||||
|
|
||||||
|
$ vim -p !touch:*
|
||||||
|
$ vim -p !touch:2-4
|
||||||
|
$ vim -p !:2*
|
||||||
|
Expands argument ranges from the last `touch` command. `*`, `1-*` and `1*` are
|
||||||
|
synonymous. If no string is specified, like `!:*`, the last command is used
|
||||||
|
|
||||||
|
$ vim -o !touch:1*
|
||||||
|
Open a new window for every argument in the most recent command starting with
|
||||||
|
`touch`
|
||||||
|
|
||||||
|
$ ^touch^vim -o^
|
||||||
|
$ !!:s/touch/vim -o
|
||||||
|
$ !!:&
|
||||||
|
Replay the last command replacing the first instance of `touch` with `vim -o`.
|
||||||
|
The third line replaces `&` with the last substitution
|
||||||
|
|
||||||
|
$ vim -o !touch:*:gs/html/md
|
||||||
|
Recall all the arguments of the last `touch` command. Replace all instances of
|
||||||
|
`html` with `md` then pass those to `vim -o`
|
||||||
|
|
||||||
|
$ cat !!:$:s/machine/human
|
||||||
|
Substitute in the last argument from the previous command with `human`
|
||||||
|
|
||||||
|
<C-r>
|
||||||
|
<C-s>
|
||||||
|
Search backward or forward for input string. Use multiple times to scroll
|
||||||
|
|
||||||
|
awk '{a[NR] = $0} END { for (i = NR; i > 0; i--) print a[i] }' # rev lines
|
||||||
|
<C-r># rev lines
|
||||||
|
Replays the tagged command. Use trailing comments to act as a tag
|
||||||
|
|
||||||
|
diff ~/Downloads/{before,after}.txt
|
||||||
|
Checks if `before.txt` and `after.txt` are different. Braces are duplicated
|
||||||
|
|
||||||
|
$ !if:gs/$c/$a
|
||||||
|
Replace all the variables $c with $a in the previous command starting with if
|
||||||
|
|
||||||
|
So the general structure of recall is
|
||||||
|
```
|
||||||
|
!<cmd-identifier>[:<arg-range>][:<operator>]
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Automated interactive input
|
||||||
|
$ yes | rm -ir /deep_dir
|
||||||
|
Bypasses interactive y/N prompt given by the `rm` command for every thing in that
|
||||||
|
directory. `yes` prints an infinite number of 'y\n' to any program
|
||||||
|
|
||||||
|
$ printf 'y\nn\ny\n' | rm -ir /small_dir
|
||||||
|
Will remove the first and third file automatically, then ask you for further
|
||||||
|
input
|
||||||
|
|
||||||
|
$ rm -ir /deep_dir < pre_made_input.txt
|
||||||
|
Enters the file contexts to the interactive prompt. Line breaks are like '\n'.
|
||||||
|
Very helpful if you're using this order of input over and over
|
||||||
|
|
||||||
|
###### Bash scripting
|
||||||
|
Bash is an awful scripting language in every sense except portability. Always
|
||||||
|
install and use `shellcheck` after writing a script
|
||||||
|
|
||||||
|
bash_script.sh
|
||||||
|
#!/bin/bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#!/usr/bin/env -S awk -f ${SOMEFILE}
|
||||||
|
Use shebang at the top to declare an interpreter. Using `env` is considered more
|
||||||
|
portable, though the `-S` option is required for anything longer than one word
|
||||||
|
|
||||||
|
$ echo ${myvar:-not here}
|
||||||
|
$ echo ${myvar:-"not here"}
|
||||||
|
Expands to `$myvar` if it's set, otherwise expands to string "not here"
|
||||||
|
|
||||||
|
$ for i in $(seq 0 9); do python -c "print(ord('$1'))" & done
|
||||||
|
Asynchronously print the ASCII codes for range `[0, 9]`
|
||||||
|
|
||||||
|
###### Other Bash uses
|
||||||
|
|
||||||
|
$ compgen -c git
|
||||||
|
See the possible completion for the given word. This is what tab uses
|
||||||
|
|
||||||
|
$ time bash -c "make && ./a.out; rm ./a.out"
|
||||||
|
Times multiple separate bash commands
|
||||||
|
|
||||||
|
## Ed for terminal file editing
|
||||||
|
Ed is the original text editor for Unix systems, which still is useful for batch
|
||||||
|
editing scripts. Ranges are very similar to vim's
|
||||||
|
|
||||||
|
$ ed -p '> :' file1
|
||||||
|
Open `file1` with ed. Useful for writing a script
|
||||||
|
|
||||||
|
:n Print the current line enumerated
|
||||||
|
:100 Moves to line 100 and prints it
|
||||||
|
:ka Set a mark `a`
|
||||||
|
:'a Move to mark `a`
|
||||||
|
:i Open line above current line in insert mode. Like vim's `o`
|
||||||
|
:a Open line below current line in insert mode. Like vim's `O`
|
||||||
|
. Exit insert mode. Should be the only character on the line
|
||||||
|
Various basic commands. Most commands accept ranges, like vim's. Unlike vim, all
|
||||||
|
commands operate on entire lines at once
|
||||||
|
|
||||||
|
:g/Style/p\
|
||||||
|
a\
|
||||||
|
Style line is above ^^^^\
|
||||||
|
.\
|
||||||
|
n
|
||||||
|
For all lines matching the regex, run the command sequence. `\` separate lines
|
||||||
|
|
||||||
|
#### Batch editing with ex
|
||||||
|
Ex is vim's equivalent of `ed` and `ex` is symlinked as `vim -e` on many
|
||||||
|
systems. It's equivalent to vim's command line, similar to `ed`, though many
|
||||||
|
commands are different
|
||||||
|
|
||||||
|
$ ex file
|
||||||
|
$ vim -Nes file
|
||||||
|
Roughly equivalent ways of entering ex-mode. `Q` also works from within vim
|
||||||
|
|
||||||
|
:g/re/p Globally exectute a command on lines with /re/
|
||||||
|
:v/re/p Inverse of :g. Executes on all lines without /re/
|
||||||
|
:3,6co$ Copy lines [3,6] to the end of the document
|
||||||
|
:3m6 Move line 3 to line 6
|
||||||
|
:z=3 Pretty print lines in [-2,+2]
|
||||||
|
Some infrequently used vim commands are very important in ex-mode
|
||||||
|
|
||||||
|
:g/re/z3
|
||||||
|
Prints all the lines and line numbers that contain regex `re`
|
||||||
|
|
||||||
|
:g/bash/exe "normal! cfish\<esc>" | undo | nu
|
||||||
|
Changes every line with "bash" to "fish", undoes that, then prints the line
|
||||||
|
|
||||||
|
:g/string/nu | g/num/nu
|
||||||
|
Does NOT print all the lines with `string` or `num`. This prints all the lines
|
||||||
|
with `string` then reprints them if they also have `num`. `:g` only uses a new
|
||||||
|
line to delimit its commands from the next set!
|
||||||
|
|
||||||
|
Batch editing style (in bash):
|
||||||
|
1. Here-string: For only one command, here-strings are a quick and easy choice
|
||||||
|
|
||||||
|
$ for f in $(find ~/); do vim -Nes <<<"g/re/p"; done
|
||||||
|
Prints all lines with `re` in the home directory. Be careful chaining with `:g`
|
||||||
|
|
||||||
|
2. Here-ansi-c-string: Allows including c-style escape sequences
|
||||||
|
|
||||||
|
$ for f in $(find ~/); do vim -Nes <<< $'g/re/nu\n3'; done
|
||||||
|
Prints all lines with `re` then moves to line 3. Often can be avoided with `|`
|
||||||
|
|
||||||
|
3. Here-documents: Probably the best choice for quick batch edits
|
||||||
|
|
||||||
|
$ for file in $(fd -at type subs_)
|
||||||
|
do
|
||||||
|
vim -Nes $file <<'DOC'
|
||||||
|
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
|
||||||
|
$ | a
|
||||||
|
# ex: ff=unix:
|
||||||
|
.
|
||||||
|
wq
|
||||||
|
DOC
|
||||||
|
done
|
||||||
|
|
||||||
|
Changes The style lines and appends a modeline to files found by `fd`
|
||||||
|
|
||||||
|
$ for file in ~/.bash*; do vim -Nes $file <<EOF
|
||||||
|
a
|
||||||
|
# ex: set syntax=bash:ff=unix:
|
||||||
|
.
|
||||||
|
wq
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
Adds a mode line to all bash dot files in the home directory
|
||||||
|
|
||||||
|
4. Sourced documents: Better for recurring batch edits
|
||||||
|
|
||||||
|
$ fd -a subs_ -x ex < change_font
|
||||||
|
$ fd -a subs_ -x vim -Nes < change_font
|
||||||
|
Changes font for all subtitle files. Similar to `vim -S $file`
|
||||||
|
|
||||||
|
#### Best practices
|
||||||
|
Use `-t file` in `fd`, otherwise `ex` may stop when it hits a directory
|
||||||
|
|
||||||
|
Recent version of `fd` seems to consume here-documents and strings. To avoid
|
||||||
|
this, use the bash `for` loop syntax as below:
|
||||||
|
|
||||||
|
$ for file in $(fd -at file .); do vim -Ne $f <<<$'nu'; done
|
||||||
|
|
||||||
|
Or with here-documents
|
||||||
|
$ for file in $(fd -at file .); do vim -Ne $f <<doc
|
||||||
|
nu
|
||||||
|
doc
|
||||||
|
done
|
||||||
|
|
||||||
|
#### Batch editing manually
|
||||||
|
fd -t file . -X awk '$0 ~ / ex:/ { print FILENAME }' | xargs -o vim
|
||||||
|
Open all files containing ` ex:` in vim as separate buffers
|
||||||
|
|
||||||
|
## Awk the programming language
|
||||||
|
AWK is an old, though surprisingly useable stream-editing language. It's a POSIX
|
||||||
|
compliant tool to bundle `grep`, `sed`, `printf`, `cut`, `xargs`, and more all
|
||||||
|
into one scripting language. Most its use comes in bash scripts or one-liners to
|
||||||
|
quickly extract information from a text stream. The man pages are really good!
|
||||||
|
|
||||||
|
Much of the standard control flow is the same as C. Variables don't need to be
|
||||||
|
initialized before use, ex: `i+=1`. Many functions will perform on `$0` if no
|
||||||
|
argument is given
|
||||||
|
|
||||||
|
#!/usr/bin/env -S awk -f
|
||||||
|
#!/usr/bin/env -S awk -F: -f
|
||||||
|
Use the string option on `env` to be able to specify the necessary `-f` option
|
||||||
|
|
||||||
|
|
||||||
|
substr(str, start_pos, chars_cut) // Cut out part of a string
|
||||||
|
length([str]) // Length of str, or $0 if no argument is given
|
||||||
|
index(str, search_str) // Find starting index of match in str
|
||||||
|
match(str, /reg/) // Return index. Set RSTART and RLENGTH
|
||||||
|
split(str, array, fs) // Split str into array elements on FieldSeperator
|
||||||
|
sub(/reg/, new_str, str) // Subs new_str for first /reg/ match in str
|
||||||
|
sub("match", new_str, str) // Subs new_str for first string "match" in str
|
||||||
|
gsub(/reg/, new_str, str) // Above just global
|
||||||
|
The core awk functions with odd argument order
|
||||||
|
|
||||||
|
printf, sprintf, system, tolower, toupper, exp, log...
|
||||||
|
Core awk functions without odd argument order
|
||||||
|
|
||||||
|
### Built in variables
|
||||||
|
NR Current line's number. Literally "number of reads". Starts at 1
|
||||||
|
NF Number of fields in this line. `$NR` expands to the last field's value
|
||||||
|
RSTART Field number of last `match()`
|
||||||
|
RLENGTH How many characters long the last `match()` was
|
||||||
|
$0 The entire line of text
|
||||||
|
$1 Where `1` is the `1th` field in the line
|
||||||
|
|
||||||
|
### Regular expression
|
||||||
|
Regular expressions are supported. They're a separate type from strings. Unlike
|
||||||
|
most modern regex interpreters, escape sequences such as `\s` and `\d` aren't
|
||||||
|
supported. Instead use POSIX compliant versions `[:space:]` and `[:digit:]`
|
||||||
|
|
||||||
|
Inverting a regex is done by defining a `!` in front. For example
|
||||||
|
$0 !~ /hello/
|
||||||
|
$0 ~ !/hello/
|
||||||
|
$0 ~ /[^(hello)]/
|
||||||
|
|
||||||
|
If you want to store a regex in a variable for later use, DO NOT store an actual
|
||||||
|
regex type. Store the regex as a string instead, effectively replacing the
|
||||||
|
encapsulating `/` with `"`
|
||||||
|
|
||||||
|
my_regex = "hello[:space:]+you"
|
||||||
|
$0 ~ my_regex
|
||||||
|
Notably, using a regex instead of a string in this situation results in odd
|
||||||
|
silent errors that mostly work. These can be hard to debug, so watch out
|
||||||
|
|
||||||
|
### Recipes
|
||||||
|
$ cat file.txt | awk 'tolower($0) ~ /word/ { print $0 }'
|
||||||
|
$ cat file.txt | awk 'tolower($0) ~ /word/'
|
||||||
|
$ cat file.txt | grep -i 'word'
|
||||||
|
Searches through given piped text for 'word' in any casing
|
||||||
|
|
||||||
|
$ cat file.txt | awk -F ',' '
|
||||||
|
{ commas += NF - 1 }
|
||||||
|
END { print "Commas counted:", commas }'
|
||||||
|
Counts the number of commas in a file.
|
||||||
|
|
||||||
|
$ awk -F '\t' '{ print $0 }' demo.txt
|
||||||
|
$ awk -F '\t' demo.txt
|
||||||
|
Uses tabs are a files separator between "lines"
|
||||||
|
|
||||||
|
$ current_window_id=$(chrome-cli list windows | awk -F ' ' \
|
||||||
|
'NR == 1 { gsub(/[\[\]]/, "", $1); print $1 }')
|
||||||
|
Parses the window id from `[999] Some Title` to `999`
|
||||||
|
|
||||||
|
$ ls -la | awk 'match($NF, /[0-9]+/) { print substr($NF, RSTART, RLENGTH) }' >
|
||||||
|
coffees.nh
|
||||||
|
Checks if the last argument is a string of consecutive numbers. Notice how `$NF`
|
||||||
|
uses that `NF` is the last number to index the last field like `$3`
|
||||||
|
|
||||||
|
### Advanced examples
|
||||||
|
END {
|
||||||
|
arr["hello"] = 2; arr["other"]++; arr["some"] += 10;
|
||||||
|
|
||||||
|
printf "Hello: %d, Other: %d, Some: %d, None: %d\n",
|
||||||
|
arr["hello"], arr["other"], arr["some"], arr["none"];
|
||||||
|
}
|
||||||
|
>>> Output: Hello: 2, Other: 1, Some: 10, None: 0
|
||||||
|
Arrays can be indexed by strings! This allows for counting words or lines
|
||||||
|
|
||||||
|
$ awk '!($0 in uniq) { uniq[$0]; print }' duplicates.txt > uniques.txt
|
||||||
|
Removes duplicate lines. This uses the relational operator `(expr, expr... arr)`
|
||||||
|
to check if an element with the string's index has been initialized in the array
|
||||||
|
|
||||||
|
$ awk '!unique[$0]++' duplicates.txt > uniques.txt
|
||||||
|
Removes duplicate lines. This exploits awk's automatic initialization of
|
||||||
|
variables with falsey values, 0 here, then turns that index truthy with `++`
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ex: set ft=markdown tw=80: -->
|
8
notes/shell/unix_file_times.md
Normal file
8
notes/shell/unix_file_times.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Unix file times
|
||||||
|
Unix files store 3 time stamps: Modified, Accessed, Changed. These can be seen
|
||||||
|
with `ls -l`. The `stat` command can list these times as well, particularly with
|
||||||
|
something like `--format='%y'`
|
||||||
|
|
||||||
|
`touch` can change times directly. To use the times of another file, provide it
|
||||||
|
via the `-r` option, then constrain the times you want to change. For example
|
||||||
|
the `-m` flag will only copy over the modified time
|
32
notes/vim/tee.md
Normal file
32
notes/vim/tee.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Tee command
|
||||||
|
Duplicate piped output between a file and the stdout
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo echo "something" > root_file
|
||||||
|
```
|
||||||
|
|
||||||
|
This won't work since output redirection is always done with user privileges.
|
||||||
|
Instead we use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "something" | sudo tee root_file
|
||||||
|
echo "something" | sudo tee root_file &>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the redirection will be executed with root privileges. Stdout can be
|
||||||
|
silenced to get the same effect as before. Tee can also copy output to multiple
|
||||||
|
files, or act like `>>` with `-a`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "something" | tee file1 | tee file2 > file3
|
||||||
|
```
|
||||||
|
|
||||||
|
It's very useful in vim, when you forget to use root privileges when editing a
|
||||||
|
root-only file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
:w ! sudo tee %
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that neovim doesn't support interactive sessions through external commands
|
||||||
|
yet, so this only works in vim
|
46
notes/vim/vifm_moving_files.md
Normal file
46
notes/vim/vifm_moving_files.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Vifm: Moving files
|
||||||
|
|
||||||
|
There are a few ways to move files in vifm, all of which hinge on using a
|
||||||
|
selection paired with some sort of command
|
||||||
|
|
||||||
|
### Selections
|
||||||
|
|
||||||
|
These selections and filters get cleared once you change directories
|
||||||
|
|
||||||
|
1. Not selecting anything implicitly selects anything under your cursor
|
||||||
|
2. `za` toggles dotfile visibility
|
||||||
|
3. `t` adds a single file to the selection from the directory
|
||||||
|
4. `V` visual mode selects files in a range
|
||||||
|
5. `=` quick filter that is case-sensitive
|
||||||
|
|
||||||
|
These filters are permanent, in that they're retained between directory
|
||||||
|
switches and apply to all directories
|
||||||
|
|
||||||
|
1. `zf` adds the current selection to the permanent filter
|
||||||
|
2. `:filter <regex>` hides all matching files in all directories
|
||||||
|
3. `:filter! <regex>` inverse of above filter, only shows these files
|
||||||
|
|
||||||
|
These are then controlled with
|
||||||
|
|
||||||
|
- `zO` Unset the permanent filter
|
||||||
|
- `zR` Stash the permanent filter
|
||||||
|
- `zM` Pop the stashed permanent filters
|
||||||
|
|
||||||
|
These are best paired with visual mode to quickly select a bunch of files
|
||||||
|
|
||||||
|
### Moving files
|
||||||
|
|
||||||
|
A simple `:m` will move all selected files to the location in the other pane.
|
||||||
|
Using `:sync %d` can set the opposing pane to the current one
|
||||||
|
|
||||||
|
Alternatively you can yank into a register, say `"ay`, then move all files in
|
||||||
|
the register to your current location with `:put a`
|
||||||
|
|
||||||
|
Also, don't forget there are other tools that can be better for the job. For
|
||||||
|
example batch renaming should be done through `mmv`
|
||||||
|
|
||||||
|
```
|
||||||
|
:!mmv './*_EP*.srt' './Documents/subtitles/kaguya_S1_#1.srt'
|
||||||
|
```
|
||||||
|
|
||||||
|
Bash for-loops paired with `fd` or `rg -l` can be used for fine-tuning too
|
17
notes/vim/vim_backtick_expansion.md
Normal file
17
notes/vim/vim_backtick_expansion.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Vim backtick expansion
|
||||||
|
|
||||||
|
```
|
||||||
|
:h backtick-expansion
|
||||||
|
```
|
||||||
|
|
||||||
|
Essentially allows command substitution with shell or vim commands. Requires a
|
||||||
|
lot of escaping special symbols though
|
||||||
|
|
||||||
|
```bash
|
||||||
|
:e `mktemp`
|
||||||
|
:e `=tempname()`
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit a new temporary file. Very useful in gui contexts when you just quickly
|
||||||
|
need to jot something down. The equal sign in the second line expands a vim
|
||||||
|
function instead of calling a shell
|
53
notes/vim/vim_macros.md
Normal file
53
notes/vim/vim_macros.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Vim Power Macros
|
||||||
|
|
||||||
|
### Recording
|
||||||
|
|
||||||
|
When recording macros, best practice is to start with a `0` motion and try to
|
||||||
|
use absolute motions to the line like `A` not `w`
|
||||||
|
|
||||||
|
Macros are a register, so they can be edited the same way as one. In fact `@` is
|
||||||
|
just a shortcut for `:normal <paste-register-here>`. They can be viewed with
|
||||||
|
`:reg`
|
||||||
|
|
||||||
|
Modifying macros:
|
||||||
|
- `"lp` paste register `l`
|
||||||
|
- `<C-v><C-k>` literally inserts `<C-k>` as a key motion. Useful for pseudo-esc
|
||||||
|
|
||||||
|
Saving macros:
|
||||||
|
- `"lyy` copy line into register `l`
|
||||||
|
- `:'<,'>y l` copy selected line into register `l`
|
||||||
|
- `{Visual}"ly` copy selection into register `l`. Doesn't have `<C-j>` at the end
|
||||||
|
|
||||||
|
On the line:
|
||||||
|
- `<C-r>l` pastes the `l` register in insert mode
|
||||||
|
- `:let @l = "<rec>"` sets the `l` register as `<rec>`
|
||||||
|
- `:let @L = "<rec>"` appends `<rec>` to register `l`
|
||||||
|
- `"i\<esc>"` in a string escapes to literal key strokes, like `<C-v>` inserts
|
||||||
|
|
||||||
|
Escaping keystrokes, from the last example, only works with double quoted
|
||||||
|
strings. You can check in `:reg` to see the literal expansion
|
||||||
|
|
||||||
|
### Replaying macros
|
||||||
|
The older convention for batch macros was adding `j` at the end of the macro,
|
||||||
|
and using absolute motions:
|
||||||
|
- `4@l` replay the macro 4 times
|
||||||
|
|
||||||
|
A newer solution is to execute registers over command line through `:normal`.
|
||||||
|
Macros executed this way always starts in the left-most column, so prepend `0`
|
||||||
|
to your macro for consistency
|
||||||
|
|
||||||
|
Command style:
|
||||||
|
- `:norm[al][!] @l` can be used to replay macros. Keep the `!` to not use maps
|
||||||
|
- `:'<,'>norm! @l` replays the macro over every select line
|
||||||
|
- `:g/re/norm! @l` replays the macro over lines with a matching regex
|
||||||
|
|
||||||
|
Oddly, while `:norm! @l` doesn't see maps for `@l`, it will see mapping in the
|
||||||
|
register internally. So
|
||||||
|
|
||||||
|
```
|
||||||
|
:nnoremap <C-k> <esc>
|
||||||
|
:let @l = "Ihello\<C-k>"
|
||||||
|
:norm! @l
|
||||||
|
```
|
||||||
|
|
||||||
|
will still read `<C-k>` as `<esc>` when executing
|
28
notes/vim/vim_unicode_special_keys.md
Normal file
28
notes/vim/vim_unicode_special_keys.md
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Executing special keys
|
||||||
|
|
||||||
|
Vim's `:exe[cute]` will read special keys when they're escaped in double quotes:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
exe "normal! i\<C-v>u049c\<C-v>u03b1\<C-v>u03c4\<C-v>u212f!\<ESC>"
|
||||||
|
" Writes Ҝατℯ
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use this to quickly script difficult macros, like the one above
|
||||||
|
|
||||||
|
```
|
||||||
|
:exe "normal! i\<C-v>u049c\<C-v>u03b1\<C-v>u03c4\<C-v>u212f!\<ESC>"<CR>
|
||||||
|
```
|
||||||
|
|
||||||
|
# Effective Unicode in vim
|
||||||
|
|
||||||
|
```
|
||||||
|
Demo unicodes: │┌┴─┐
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `ga` in vim to display encoding information about the character under the
|
||||||
|
cursor. We'll use the hex value. In insert mode use `<C-v>u` followed by the hex
|
||||||
|
number to type in Unicode literally. The above can be written with
|
||||||
|
|
||||||
|
```
|
||||||
|
:normal! i<C-v>u2502<C-v>u250c<C-v>u2500<C-v>u2510<ESC>
|
||||||
|
```
|
Loading…
Reference in a new issue