Reorganize notes
This commit is contained in:
parent
6221f1f520
commit
9676b6e830
39
bin/notes
39
bin/notes
|
@ -1,36 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
# Read notes files from ~/.configs_pointer/notes
|
||||
if [[ $1 =~ '-h' ]]; then
|
||||
printf 'Open notes files from ~/.configs_pointer/notes\n'
|
||||
print_help() {
|
||||
cat <<HELP
|
||||
Quickly open notes files from ~/.configs_pointer/notes
|
||||
|
||||
No arguments required
|
||||
HELP
|
||||
}
|
||||
|
||||
if [[ -n "$1" ]]; then
|
||||
print_help
|
||||
exit 0
|
||||
elif ! [[ -h ~/.configs_pointer ]]; then
|
||||
cat <<ERR
|
||||
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'
|
||||
printf 'Please set up a symlink ~/.config_pointer to the configs directory\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Fzf for notes file
|
||||
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
|
||||
|
||||
cd ~/.configs_pointer/notes || exit 2
|
||||
declare -r notes_file="$(fd -e 'md' | fzf)"
|
||||
|
||||
# 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}"
|
||||
elif command -v vim &>/dev/null; then
|
||||
vim -R "${notes_files}"
|
||||
vim -R "${notes_file}"
|
||||
elif command -v bat &>/dev/null; then
|
||||
bat --paging=always "${notes_file}"
|
||||
else
|
||||
less "${notes_file}"
|
||||
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