//nuacht.flounder.online/gemlog
<name>nuacht</name>
<title>mkisofs</title>
<updated>2023-09-20T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-09-20:/gemlog/2023-09-20-mkisofs.gmi</id>
<content type="text/plain"># mkisofs
To make an ISO of a directory, just use:
```
mkisofs -o filename.iso directory/
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-09-20-mkisofs.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Strings in Bash</title>
<updated>2023-07-20T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-07-20:/gemlog/2023-07-20-bash-strings.gmi</id>
<content type="text/plain"># Strings in Bash

```
$ STR="0123Linux9"
$ echo ${STR:4:5}
Linux
```
(from baeldung.com)</content>
<link href="//nuacht.flounder.online/gemlog/2023-07-20-bash-strings.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>7zip</title>
<updated>2023-07-07T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-07-07:/gemlog/2023-07-07-7zip.gmi</id>
<content type="text/plain"># 7zip

To create:
```
7z a secure.7z * -pSECRET

Where:
7z : executable
a : add to archive
secure.7z : destination archive
* : add all files from current dir to archive
-pSECRET : specify the password "SECRET"
```

To open:
```
7z x secure.7z
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-07-07-7zip.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Docker (RPi3B)</title>
<updated>2023-07-02T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-07-02:/gemlog/2023-07-02-docker.gmi</id>
<content type="text/plain"># Docker (RPi3B)

## Install Docker
curl -sSl https://get.docker.com | sh
sudo usermod -aG docker pi
docker (check that we get output).

## Docker Compose
pip3 install docker-compose
(log out and back in)

## Install a Docker application
mkdir -p ./DockerContainers/<app-name>/config:/config
cd DockerContainers/<app-name>/
nano docker-compose.yml (and add the config from whatever source shares it online)
docker-compose up -d

## docker run cannot be issued twice for the same "thing". docker start is needed subsequently. 
See here for details:
=> https://stackoverflow.com/questions/31697828/docker-name-is-already-in-use-by-container</content>
<link href="//nuacht.flounder.online/gemlog/2023-07-02-docker.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>HTTP</title>
<updated>2023-06-05T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-06-05:/gemlog/2023-06-05-HTTP.gmi</id>
<content type="text/plain"># HTTP
## Redirects
With just HTML, this method works
```
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="refresh" content="0; url='http://mosuíomh.ie/'" />
 </head>
 <body>
 <p>You will be redirected to mosuíomh.ie now.</p>
 </body>
</html>
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-06-05-HTTP.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Gemini Server</title>
<updated>2023-04-27T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-04-27:/gemlog/2023-04-27-gemini-server.gmi</id>
<content type="text/plain"># Gemini Server
## Download agate (server) binary.
https://github.com/mbrubeck/agate
gemini://qwertqwefsday.eu/agate.gmi

## Create
* A folder for capsule that uses domain name with tld, eg; oro.mo.bhaidin
* A script to launch agate against your capsule:
```
#!/bin/bash
agate --hostname oro.mo.bhaidin --content ~/path/to/oro.mo.bhaidin
```

## Crontab
Set crontab to launch the script after reboot with:
```
@reboot sleep 60; ~/serve/gael.agate
```
> Agate creates a .certificates directory will be created containing per-capsule certificates.

> Note: a capsule is a site in gemini lingo.</content>
<link href="//nuacht.flounder.online/gemlog/2023-04-27-gemini-server.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Home Server Setup</title>
<updated>2023-04-26T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-04-26:/gemlog/2023-04-26-home-server-setup.gmi</id>
<content type="text/plain"># Home Server Setup
After a disk failing I've decided to rebuild my server from scratch and document it here. It serves:

## Contents
- Base System: RPi 3 & SSD dock
- Connectivity: Samba and SSH
- Gemini: agate
- HTTP: lighttpd
- Scripts
- Configs


## Base System: RPi 3 & SSD dock
1. I used rpi-imager and selected the image that facilitates USB booting. It's available in a sub menu. Boot this without other peripherals and it flashes the Pi so that it can boot without the SD card in future.

2. Use rpi-imager again to install the "Lite" version of Raspian. Once selected, click the cog/gear icon and choose to enable SSH since it's a server system. We don't need a keyboard, mouse and monitor for this. Set your hostname and other preferences here. Then select your target device; your connected SSD drive and click "Write" to begin writing the operating system to the SSD. Afterwards, you can remove it from your computer, connect it to the Pi and boot the Pi with the ethernet cable connecting it to your router.

From here, you have a base system that you can SSH into and install software on.

## Connectivity: Samba and SSH
SSH is best in most cases and already configured, but once in a while being able to mount a share is a huge help.

Install samba and set up shares. See //nuacht.flounder.online/gemlog/2022-07-12-samba.gmi for details

## Gemini: agate
Download the agate binary and run the command against your domain directory. See here for notes, including crontab note to survive reboots: https://nuacht.flounder.online/gemlog/2023-04-27-gemini-server.gmi

## HTTP: lighttpd
```
sudo apt install lighttpd
```
> This package is becoming harder to find in repositories because it's so old and unmaintained. There might be better alternatives out there these days.
```
nano /etc/lighttpd/lighttpd.conf
```
Update this file to point to where your content is actually stored. Mine is ~/<path-to-site>/

It runs after booting automatically but if you need to restart it (maybe to pick up config changes), just issue:
```
service lighttpd restart
```

Some expected files are symlinked. Should those need to be recreated, do:
```
for f in *.abc; do ln -sf $(pwd)/$f ~/path/to/destination/; done
```

## Scripts: 
### crontab
User crontabs are stored in /var/spool/cron/crontabs. Check your backups here to retrieve old values.
### CDXL converter
### tmux
Full tmux entry here https://nuacht.flounder.online/gemlog/2022-07-13-tmux.gmi
### also restore:
~/.bashrc

### Script Dependencies
lynx(?)
libxml2-utils
certificates for Freeshell.de so files can be transferred without interaction

## Config files to restore via scp(may overwrite work done above)
/etc/lighttpd/lighttpd.conf
~/.certificates (belonging to agate)
~/.nanorc should contain:
```
set softwrap
set positionlog
```

## One-off commands to run
Disable annoying message with:
```
sudo raspi-config nonint do_wifi_country XX
```

</content>
<link href="//nuacht.flounder.online/gemlog/2023-04-26-home-server-setup.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Error mounting /dev/sdb2 wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error</title>
<updated>2023-04-24T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-04-24:/gemlog/2023-04-24-error-mounting.gmi</id>
<content type="text/plain"># Error mounting /dev/sdb2 wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error

Running dmesg showed a "bad geometry" error:
```
kern :warn : [ +35.991538] EXT4-fs (sdb2): bad geometry: block count 29239414 exceeds size of device (29239413 blocks)
```

To fix, on the unmounted partition: 
```
e2fsck -f /dev/XXX
resize2fs /dev/XXX
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-04-24-error-mounting.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>mutt</title>
<updated>2023-03-22T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-03-22:/gemlog/2023-03-22-mutt.gmi</id>
<content type="text/plain"># mutt

## Compose new and send
```
Q - query address book to find contact 
m - new mail (manual e-mail address entry)
(save and exit editor when message has been written)
a - attach file?
y - send message
```

## Reply to a message
```
r - reply
(save and exit editor when message has been written)
a - attach file?
y - send message
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-03-22-mutt.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>aliases</title>
<updated>2023-03-19T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-03-19:/gemlog/2023-03-19-alias.gmi</id>
<content type="text/plain"># aliases

In .bashrc, you can say something like
```
alias l='ls --color=auto'
```
and you can then just type 'l' followed by return to run the ls command.


For something more advanced, you can have an alias call a script to check a conditition before allowing the command to run. This is helpful in my git sandbox where the index.html file is sometimes a dummy file, since it faces the internet. I don't want to check that in by accident - I want to swap the dummy for the real one before git ever executes anything.

So my alias for git now calls a script to handle all of this. Typing git from a bash terminal, or any terminal that uses .bashrc will do this:
```
alias git='/home/pi/bin/gitcheck.sh'
```

Then the script itself checks the contents of index.html for the contents that are in the real file. If they are there, it also checks that the file size is above 100k, since this is also a property of the real file. The dummy file is tiny in comparison. I'm then confident to let git do it's thing, which I do by calling it with the $ parameters to include up to five arguments. I assume five is enough:
```
#!/bin/bash

# git should not check in our dummy index.html to the optimumhealth.ie repo
# so if it doesn't contain text we know should be there, it's the dummy and we abort
res=$( grep -i "optimum health" /home/pi/http/oh.ie/index.html | wc -w )
if [ $res == 0 ]; then 
 echo "You can't use git while the wrong index.html is in place"; exit; 
elif [ $(wc -c < /home/pi/http/oh.ie/index.html) > 100000 ]; then
 echo "Index is large and contains our keywords. Note: git limited to 5 arguments by bin/gitcheck.sh";
 git $1 $2 $3 $4 $5;
fi
bin/gitcheck.sh (END)
```

Now when I try to run a git command with the dumming index file in place, it saves me:
```
You can't use git while the wrong index.html is in place
```

But when the correct index file is in place, it allows the git commands to be executed:
```
$ git status
Index is large and contains our keywords. Note: git limited to 5 arguments by bin/gitcheck.sh
On branch main
Your branch is up to date with 'origin/main'.

...

no changes added to commit (use "git add" and/or "git commit -a")

```</content>
<link href="//nuacht.flounder.online/gemlog/2023-03-19-alias.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>static website using Grav</title>
<updated>2023-03-14T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-03-14:/gemlog/2023-03-14-static-website-from-grav.gmi</id>
<content type="text/plain"># static website using Grav

Grav is a very good and fast CMS system. It´s minimalistic with no database and is based on markdown. There are just three page types;

* Standard page
* Modular page (composite of other pages / blocks)
* Blog pages

Since I either self-host or use gitlab, I´m not interested in the webserver / PHP side of things. In fact, I´d prefer to omit them completely since the current gitlab setup works so seamlessly.

## Solution
1) Use Grav locally to create or update the site
2) Use HTTraQt to clone the site to pure HTML files and sync _those_ to gitlab
3) Tóg leathlá ...</content>
<link href="//nuacht.flounder.online/gemlog/2023-03-14-static-website-from-grav.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>tar</title>
<updated>2023-02-28T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-02-28:/gemlog/2023-02-28-tar.gmi</id>
<content type="text/plain"># tar

## create archive
tar cf <filename.tar> <file1> <file2> ...

## extract archive
tar xf <filename.tar></content>
<link href="//nuacht.flounder.online/gemlog/2023-02-28-tar.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>git</title>
<updated>2023-02-26T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2023-02-26:/gemlog/2023-02-26-git.gmi</id>
<content type="text/plain"># git 

## git clone <url>
Copy a git repository to local machine

## git clone --branch <branchname> <remote-repo-url>
Clone a branch instead

## git add <filename>
Choose files to be uploaded / commited

## git add -A
Instead of choosing, just include all changes automatically, please

## git commit -m "<message>"
Add note to the commit

## git push
Send / commit the files to the repository

## git branch -a
List all git branches

## git diff HEAD@{1}
Where n=1, diff existing code with previous commit. If n=2, compare with two commits ago.

## undo a git add
git reset <file> or <directory>

# Initial Setup
Instructions: https://docs.gitlab.com/ee/user/ssh.html

Client side:
1. ssh-keygen -t ed25519 -C "private key for gitlab"
2. (set a filename)
3. upload contents of .pub key to https://gitlab.com/-/profile/keys
4. add an entry to ~/.ssh/config with the following:
```
Host gitlab.com
 Hostname altssh.gitlab.com
 User git
 Port 443
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/gitlab.ophe.oh 
 #(assuming gitlab.ophe.oh is the name set in step 2)
```
5. Run this command to test: ssh -T git@gitlab.com

## errors
```
git@gitlab.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
Running these two commands fixes this for me:
```
eval `ssh-agent -s`
ssh-add ~/.ssh/gitlab_id_rsa
```
But, this was required every time after login so what actually fixed it permanently was to apt install keychain, and then append this to .bashrc:
```
eval $(keychain -q)
```

## SSH key expiry
For this I generated a new key:
```
ssh-keygen -t rsa -b 4096 -C "<identifier or email-address>"
```
I added the public key contents to gitlab settings->SSH keys.
Then tested with ssh -T git@gitlab.com.

The next step was necessary but possibly only because of a previous error:
```
git remote remove origin
git remote add origin git@gitlab.com:<project>/repo.git
```</content>
<link href="//nuacht.flounder.online/gemlog/2023-02-26-git.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>bluetooth from the terminal</title>
<updated>2022-09-30T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-30:/gemlog/2022-09-30-bluetooth.gmi</id>
<content type="text/plain"># bluetooth from the terminal
Key commands:
```
devices / paired-devices
pair
connect
## list devices
Use 'paired-devices' or 'devices' depending on desired specifity.
```
# paired-devices
Device 52:82:1E:6E:51:A3 Flyingtiger307 
Device AC:6A:34:9A:DE:11 Hang Up
Device FC:66:2F:E0:E8:3B iFónín 12
```

Then connect to your choice. For Hang Up device, that would be:
```
connect AC:6A:34:9A:DE:11
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-30-bluetooth.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>SSH</title>
<updated>2022-09-21T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-21:/gemlog/2022-09-21-ssh.gmi</id>
<content type="text/plain"># SSH

## Allow client to ssh into server with cert instead of password
On the client machine:
~/.ssh/config should contain something like this
```
Host myhost
 HostName myhost.com
 User me
 IdentityFile ~/.ssh/id_rsa (or whatever your is called)
```

Then
```
ssh-keygen
```
Press Enter on password prompt twice to create a passwordless cert (not recommended, but fine for hobby use).

Then copy your public key to the server:
```
ssh-copy-id pi@freebsd.local
```

Nó need to log into the server if you already know the password.
Now you can ssh in and won´t be prompted for password (You may have to enter password the first time).

## list remote directory contents
```
ssh user@host ls -l /some/directory
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-21-ssh.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>Cannot set LC_ALL to default locale: No such file or directory</title>
<updated>2022-09-21T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-21:/gemlog/2022-09-21-locale-error.gmi</id>
<content type="text/plain"># Cannot set LC_ALL to default locale: No such file or directory

This error appeared every time a new application was installed via apt get. Solution:

```
 export LC_ALL="C.UTF-8"
 sudo dpkg-reconfigure locales
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-21-locale-error.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>processes</title>
<updated>2022-09-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-13:/gemlog/2022-09-13-Linux-processes.gmi</id>
<content type="text/plain"># processes

## Pause and resume process
```
kill -STOP ${PID}
kill -CONT ${PID}
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-13-Linux-processes.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>ffmpeg</title>
<updated>2022-09-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-13:/gemlog/2022-09-13-ffmpeg.gmi</id>
<content type="text/plain"># ffmpeg

## combine segments
```
$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
 
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
```

## add optional subtitles 
```
ffmpeg -i infile.mp4 -i infile.srt -c copy -c:s mov_text outfile.mp4
```

## time-shift subtitle file
```
ffmpeg -itsoffset 0.7 -i original.vtt adjusted.srt
```

## combine video and audio without reencoding
```
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a copy output.mp4
```

## convert losslessly (v fast)
```
ffmpeg -i example.mkv -c copy example.mp4
```

## convert flac to mp3. High quality
```
ffmpeg -i $f -b:a 320K $f.mp3
```

## make file streamable
```
ffmpeg -i INPUT.mp4 -c copy -movflags faststart STREAMABLE_OUTPUT.mp4
```
or
```
ffmpeg -i <input> -c:v libx264 -crf 23 -c:a aac -movflags faststart output.mp4
```

## remove a specific audio stream track
```
ffmpeg -i input -map 0 -map -0:a:2 -c copy output
 * -map 0 selects all streams from the input.
 * -map -0:a:2 then deselects audio stream 3. The stream index starts counting from 0, so audio stream 10 would be 0:a:9.
```

## video not displaying in browser (only audio). Fix:
```
ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 20 -c:a aac -b:a 160k -vf format=yuv420p -movflags +faststart output.mp4
```

## progress output only
```
ffmpeg -loglevel 0 -stats -i input.mp4 output.mp4
```

## limit speed
```
-readrate 1
```
Where 1 appears as "speed=1x" on the stats output. It's worth checking first what speed your system achieves by default (10x in my current case) and choosing a relatively limited value (-readrate 6 in my current case) to keep the system cool and quiet.

## trim first 5 seconds from video
```
ffmpeg -i input.mp4 -ss 5 -vcodec copy -acodec copy output.mp4

```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-13-ffmpeg.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>DNS</title>
<updated>2022-09-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-13:/gemlog/2022-09-13-dns.gmi</id>
<content type="text/plain"># DNS

## Multiple Servers for One Domain
It's easy to have different servers share one domain name. Give each subdomain it's own DNS entry pointing to the relevant server.

## DNS problem with Vodafone router
Using ping/ssh against qualified names like freebsd.local were failing. The clue to the solution is in the name of the router: Vodafone.station. They're using .station instead of .local.

Successfully connected with:
```
ssh <user>@freebsd.station
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-13-dns.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>curl and wget</title>
<updated>2022-09-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-13:/gemlog/2022-09-13-curl-and-wget.gmi</id>
<content type="text/plain"># curl and wget

## Get HTTP headers only
```
curl -L -I domain.com
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-13-curl-and-wget.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>printf to update same line</title>
<updated>2022-09-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-09-13:/gemlog/2022-09-13-bash-output.gmi</id>
<content type="text/plain"># printf to update same line

## Update output on same line
```
printf "\rMy static $myvars composed text"
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-09-13-bash-output.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>convert mp4 to HAM video on Ubuntu</title>
<updated>2022-08-28T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-08-28:/gemlog/2022-08-28-hvconvert on linux.gmi</id>
<content type="text/plain"># convert mp4 to HAM video on Ubuntu

There is a script to convert mp4 files to .hv. It ran on 32-bit linux and won't work by default on 64-bit linux. Below are the steps I took to get it working on Ubuntu 22.04. 

## Install hvconvert
```
wget 1.node1.de/hvconvert.tgz
tar zxvf hvconvert.tgz 
```

The above fetches and extracts the conversion program. But hvconvert depends on some things we need to set up. 

## Prepare environment
You'll get an error about avconv not being found. It's functionality has since been merged into ffmpeg, so we can fake it like so:
```
sudo ln -s /usr/bin/ffmpeg /usr/bin/avconv
```

I also did the following. It's possible they aren't all necessary but since it's how I got things working I'm giving the steps as I did them.:

```
sudo dpkg --add-architecture i386
sudo apt install libc6:i386
sudo apt install libncurses5:i386
sudo apt install libstdc++6:i386
sudo apt install lib32z1
```

## Get remaining 32-bit libraries
These weren't available in the default Ubuntu repo. But I downloaded a small (50MB) ISO of Slitaz Linux which has the following libraries:

*libX11.so.6
*libXext.so.6
*libXpm.so.4
*libXrandr.so.2
*libXrender.so.1
*libxcb.so.1
*libXau.so.6
*libXdmcp.so.6

They need to be copied to /lib/i386-linux-gnu/ on your Ubuntu machine. Download them here:
=> https://archive.org/download/32-bit-libs-for-hvconvert/32-bit-libs-for-hvconvert.tar.gz

Finally, just run the program. I have an mp4 ready to test.

```
cd hvconvert
./hvconvert.sh 10sec.mp4
```

This works for me. Best of luck with it.

## Alternative
Prior to this, as a quick hack I was using Virtualbox to boot the Slitaz.iso liveCD. I would run the wget and tar commands as above and use wget to download any mp4 files I wanted to convert. Then I would use scp to send the result to the host machine like so:

```
scp output.hv gunther@192.168.1.16:/home/gunther/Movies
```

Obviously, you would use your own IP address and destination path etc.

Since this is a LiveCD, I saved the state/snapshot with Virtualbox so I could return to it at any time. However, I prefer the other method so I can remove Virtualbox.
</content>
<link href="//nuacht.flounder.online/gemlog/2022-08-28-hvconvert%20on%20linux.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>list installed packages by size</title>
<updated>2022-08-18T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-08-18:/gemlog/2022-08-18-List-installed-packages.gmi</id>
<content type="text/plain"># list installed packages by size

```
dpkg-query -W --showformat='${Installed-Size}\t${Package}\n' | sort -k1,1n
```

Note: uninstalled packages still listed or packages that have left config files behind. To strictly list installed packages:
```
dpkg-query -W --showformat='${Installed-Size}\t${Package}\t${Status}\n' | sort -k1,1n | grep installed
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-08-18-List-installed-packages.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>shrink a Virtual Box disk image (dynamic)</title>
<updated>2022-08-17T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-08-17:/gemlog/2022-08-17-shrink-virtualbox-disk.gmi</id>
<content type="text/plain"># shrink a Virtual Box disk image (dynamic)

## In the Virtual machine itself
```
sudo apt install zerofree 
```
boot into emergency mode with GRUB by pressing 'e' and appending the line beginning with 'linux' with the text 
```
systemd.unit=emergency.target
```
F10 to boot. Log in as root and then run:
```
mount -o remount,ro / #makes the partition read-only, which zerofree requires
```
Then run: 
```
zerofree -v /dev/sda1 #(or whatever you want to target)
```
Exit. Shutdown the VM and open a terminal in the host OS.

## In the host OS terminal

```
$ vboxmanage list hdds #see all virtual disks and identify the one you want
$ vboxmanage modifymedium disk ./VirtualBox/MyDebian/MyDebian.vdi --compact #substituting the path for the disk you want to target
```

Done.
</content>
<link href="//nuacht.flounder.online/gemlog/2022-08-17-shrink-virtualbox-disk.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>remove spaces from filenames</title>
<updated>2022-08-04T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-08-04:/gemlog/2022-08-04-bash-remove-filename-spaces.gmi</id>
<content type="text/plain"># remove spaces from filenames
in bash with

```
for f in *\ *; do mv "$f" "${f// /_}"; done
```

The above operates on all files in a directory.</content>
<link href="//nuacht.flounder.online/gemlog/2022-08-04-bash-remove-filename-spaces.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>tmux</title>
<updated>2022-07-13T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-07-13:/gemlog/2022-07-13-tmux.gmi</id>
<content type="text/plain"># tmux

## Common Commands
tmux new -s <session-name>		to start a new named session
Ctrl b, d	 to detach from session
Ctrl b, w list windows (interactive)

## Full Reference
```
Session Control (from the command line)
tmux					Start a new session
tmux new -s <session-name>		Start a new session with the name chosen
tmux ls					List all sessions
tmux attach -t <target-session>		Re-attach a detached session
tmux attach -d -t <target-session>	Re-attach a detached session (and detach it from elsewhere)
tmux kill-session -t <target-session> Delete session

Pane Control
Ctrl b, "	Split pane horizontally
Ctrl b, %	Split pane vertically
Ctrl b, o	Next pane
Ctrl b, ;	Previous pane
Ctrl b, q	Show pane numbers
Ctrl b, z	Toggle pane zoom
Ctrl b, !	Convert pane into a window
Ctrl b, x	Kill current pane
Ctrl b, Ctrl O	Swap panes
Ctrl b, t	Display clock
Ctrl b, q	Transpose two letters (delete and paste)
Ctrl b, {	Move to the previous pane
Ctrl b, }	Move to the next pane
Ctrl b, Space	Toggle between pane layouts
Ctrl b, ↑	Resize pane (make taller)
Ctrl b, ↓	Resize pane (make smaller)
Ctrl b, ←	Resize pane (make wider)
Ctrl b, →	Resize pane (make narrower)

Window Control
Ctrl b, c	Create new window
Ctrl b, d	Detach from session
Ctrl b, ,	Rename current window
Ctrl b, &	Close current window
Ctrl b, w	List windows
Ctrl b, p	Previous window
Ctrl b, n	Next window

Copy-Mode (vi)
Ctrl b, [	Enter copy mode
Ctrl b, G	Bottom of history
Ctrl b, g	Top of history
Ctrl b, Enter	Copy selection
Ctrl b, p	Paste selection
Ctrl b, k	Cursor Up
Ctrl b, j	Cursor Down
Ctrl b, h	Cursor Left
Ctrl b, l	Cursor Right
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-07-13-tmux.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>samba</title>
<updated>2022-07-12T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-07-12:/gemlog/2022-07-12-samba.gmi</id>
<content type="text/plain"># samba

This creates our household share that doesn't require login. Risky, but in our case all data stored here are unconfidential duplicate midea that we can afford to lose but would like easy shared access to.

```
apt install samba samba-common-bin

nano /etc/samba/smb.conf

[Share]
path = /home/pi/share
browseable = yes
writable = yes
read only = no
force user = nobody
guest ok = yes
directory mask = 0777
create mask = 0777
```

then

```
service smbd restart 
(or)
sudo systemctl restart smbd
```

Also,
```
chmod 777 /home/pi/share
```
to allow guests to have write permissions. Check existing permissions with
```
stat -c '%a' /home/pi/share
```

This is wide open to anyone in the network to read and write to. In our case, it just hosts duplicates of family media for quick access on the projector laptop.

For more serious use, create restricted shares, masks and users in the .conf file. 
For more info on create and directory mask see http://www.bodenzord.com/archives/53

# Adding users
(Almost forgot). 
sudo adduser joe
sudo smbpasswd -a joe


## Update
The chmod 777 trick was required not only to allow guests, but for some reason even registered users. This is not good security so instead here is a suggestion found online and written by 
=> https://unix.stackexchange.com/users/116972/yaegashi yaegashi

I recommend to create a dedicated user for that share and specify it in force user(see docs).

Create a user (shareuser for example) and set the owner of everything in the share folder to that user:

adduser --system shareuser
chown -R shareuser /path/to/share
Then add force user and permission mask settings in smb.conf:

[myshare]
path = /path/to/share
writeable = yes
browseable = yes
public = yes
create mask = 0644
directory mask = 0755
force user = shareuser
Note that guest ok is a synonym for public.

//end of update / footnote
</content>
<link href="//nuacht.flounder.online/gemlog/2022-07-12-samba.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>sed</title>
<updated>2022-07-11T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-07-11:/gemlog/2022-07-11-sed.gmi</id>
<content type="text/plain"># sed 

## Remove control chars
For some reason, sed wasn't matching my string variable against another text body which contained the same text. Turns out there were control characters from another encoding type at the end of the string: M-BM-.

cat $var didn't show them, but cat -A $var did. Solution:

```
$ sed 's/Ctrl+Shift+ua0 (which looks like)
$ sed 's/̲/̲u̲a̲0̲ (to be completed as usual)
$ sed 's/ / /g' mytext.txt
```

I got this answer from https://askubuntu.com/questions/357248/how-to-remove-special-m-bm-character-with-sed

## Delete from start up to and including match:
```
sed '1,/^WHATEVER$/d'
sed "1,/$my_match/d"
```

## Delete from match to end, including match:
```
sed '/TAGS/,$d'
```

## Delete range (lines 3 to 5 here)
sed '3,5d' file.txt
## Remove duplicate blank lines (but preserve at least one blank line)
'$!N; /^\(.*\)\n\1$/!P; D' file.txt

## Print selected lines (line 5 only in this case)
```
sed -n '5,5p' file.txt
```

## Get lines before match
```
sed -n '/_HEADER_/q;p' index.template
```

## Get lines after match
```
sed -e '1,/_HEADER_/ d' index.template
```

## Wrap HTML element around something
```
sed 's|www\.[^ ]*|<a href="&">&</a>|g' <newtext.txt >newtext.html
```
would wrap <a href....></a> around urls starting with www, for example.

## Rename files in current dir so that spaces are removed
```
for f in *\ *; do mv "$f" "${f// /_}"; done
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-07-11-sed.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
<title>nano</title>
<updated>2022-07-07T00:00:00Z</updated>
<id>tag:nuacht.flounder.online,2022-07-07:/gemlog/2022-07-07-nano.gmi</id>
<content type="text/plain"># nano 

Open nano and jump to a line number 13:
```
nano +13 file.sh
```

add mouse support, line numbers and $oft word wrap:
```
nano -lm$ +13 file.sh
```

Make permanent in config file
```
~/.nanorc

set linenumbers 
set autoindent
set mouse
set softwrap
set titlecolor green,black
set statuscolor cyan
set keycolor magenta
set functioncolor cyan
set numbercolor cyan
```</content>
<link href="//nuacht.flounder.online/gemlog/2022-07-07-nano.gmi" rel="alternate"></link>
<summary type="text/plain"></summary>
application/atom+xml
This content has been proxied by September (ba2dc).