Skip to content
rm all specific macos and linux specific related notes from linux-macos-admin notes doc authored by Chris's avatar Chris
......@@ -52,109 +52,6 @@
</ul>
</details>
<details>
<summary><a href="#macos">macOS</a></summary>
<ul>
<li><a href="#macos-useful-links"><strong>Useful Links</strong> macOS</a></li>
<li><a href="#ncurses">ncurses</a></li>
<li>
<details>
<summary><a href="#working-with-ssh">Working with SSH</a></summary>
<ul>
<li><a href="#working-with-brewed-openssh">Working with brewed OpenSSH</a></li>
<li><a href="#gotchas-working-with-brewed-openssh"><strong>Gotchas</strong> Working with brewed OpenSSH</a></li>
<li><a href="#tshooting-working-with-brewed-openssh"><strong>Troubleshooting</strong> Working with brewed OpenSSH</strong></a></li>
<li><a href="#todos-working-with-brewed-openssh"><strong>TODOs</strong> Working with brewed OpenSSH</a></li>
<li><a href="#setup-x11-forwarding-through-ssh">Setting Up X11 Forwarding through SSH</a></li>
<li><a href="#connecting-to-x11-server">Connecting to an X11 Server</a></li>
</ul>
</details>
</li>
<li><a href="#working-with-locales">Working with locales</a></li>
<li><a href="#working-with-users-and-groups">Working with users and groups</a></li>
<ul>
<li><a href="#useful-links-working-with-users-and-groups"><strong>Useful Links</strong> Working with users and groups</a></li>
</ul>
<li><a href="#image-processing">Image Processing</a></li>
<ul>
<li><a href="#useful-links-image-processing"><strong>Useful Links</strong> Image Processing</a></li>
</ul>
<li><a href="#xcode">Xcode</a></li>
<li><a href="#working-with-files-in-finder">Working with files in Finder</a></li>
<li><a href="#working-with-files-via-cli">Working with files via CLI</a></li>
<li><a href="#tweaking-macos-settings-from-the-cli">tweaking macOS settings from the CLI</a></li>
<li>
<details>
<summary><a href="#macos-automating-cli-tasks">macOS Automating CLI tasks</a></summary>
<ul>
<li><a href="#macos-automating-tasks-on-sierra">macOS Automating tasks on Sierra</a></li>
<li><a href="#useful-links-macos-automating-tasks"><strong>Useful Links</strong> macOS Automating tasks</a></li>
</ul>
</details>
</li>
<li><a href="#working-with-audio-on-macos">Working with Audio on macOS</a></li>
<li><a href="#working-with-filesystems">Working with filesystems</a></li>
<li><a href="#building-macos-install-boot-media">Building macOS install boot media</a></li>
<li><a href="#disk-management">Disk Management</a></li>
<ul>
<li><a href="#useful-links-disk-management"><strong>Useful Links</strong> Disk Management</a></li>
</ul>
<li><a href="#working-with-java">Working with Java</a></li>
<li>
<details>
<summary><a href="#working-with-launchd">Working with launchd</a></summary>
<ul>
<li><a href="#launchd-general-notes">launchd <strong>General Notes</strong></a></li>
<li><a href="#launchd-gotchas">launchd <strong>Gotchas</strong></a></li>
<li><a href="#useful-links-launchd"><strong>Useful Links</strong> launchd</a></li>
<li><a href="#launchd"><strong>TODOs</strong> launchd</a></li>
</ul>
</li>
<li><a href="working-with-postgres">Working with Postgres on macOS</a></li>
<li><a href="#working-with-applescript">Working with AppleScript</a></li>
<ul>
<li><a href="#useful-links-applescript"><strong>Useful Links</strong> AppleScript</a></li>
</ul>
</ul>
</ul>
</details>
<details>
<summary><a href="#linux">Linux</a></summary>
<ul>
<li><a href="#debian">Debian</a></li>
<ul>
<li><a href="#general-commands">General Commands</a></li>
<li><a href="#working-with-apt">Working with <code>apt</code></a></li>
<li><a href="#upgrading-from-jessie-to-stretch">Upgrading from Jessie to Stretch</a></li>
</ul>
<li><a href="#working-with-cron">Working with <code>cron</code></a></li>
<li><a href="#working-with-users-and-groups">Working with Users and Groups</a></li>
<li><a href="#working-with-pamd">Working with pam.d</a></li>
<li><a href="#working-with-locales">Working with locales</a></li>
<ul>
<li><a href="#useful-commands-for-working-with-locales">Useful Commands for Working with locales</a></li>
</ul>
<li><a href="#postgresql">PostgreSQL</a></li>
<ul>
<li><a href="#postgresql-backing-up-databases">PostgreSQL <strong>Backing Up databases</strong></a></li>
<li><a href="#working-with-postgres-on-debian">Working with postgres on Debian</a></li>
<li><a href="#getting-postgres-to-work-with-systemd">Getting postgres to work with systemd</a></li>
<li><a href="#working-with-psql">Working with <code>psql</code></a></li>
</ul>
<li><a href="#working-with-php">Working with PHP</a></li>
<li><a href="#working-with-nginx">Working with Nginx</a></li>
<li><a href="#working-with-mysql">Working with MySQL</a></li>
<ul>
<li><a href="#useful-links-mysql"><strong>Useful Links</strong> MySQL</a></li>
</ul>
<li><a href="#mediawiki">MediaWiki</a></li>
<li><a href="#working-with-systemd">Working with systemd</a></li>
<li><a href="#working-with-man-pages">Working with <code>man</code> pages</a></li>
<ul>
<li><a href="#useful-links-man-pages"><strong>Useful Links</strong> man pages</a></li>
</ul>
<li><a href="#working-with-ld">Working with <code>ld</code></a></li>
</ul>
</details>
<details open>
<summary><a href="#useful-links">Useful Links</a></summary>
</details>
......@@ -1002,3305 +899,6 @@ unsupported compression method 99
7z x -p 4242 /path/to/file.zip
```
<a id="macOS"></a>
## macOS [🔝](#contents)
<a id="macos-security"></a>
### Working with security related features on macOS
macOS provides a feature know as SIP _System Integrity Protection_ which basically prevents certain files and settings from being modified.
To disable **SIP** on a modern version of macOS
1. Boot into _recovery mode_ <kbd></kbd> + <kbd>r</kbd>
2. Enter the below command to disable **SIP**
```shell
csrutil disable; reboot
```
To check the status of **SIP**
```shell
csrutil status
```
<a id="useful-links-macos"></a>
### Useful Links macOS [🔝](#contents)
For a comprehensive list of changes of macOS between releases [see](https://developer.apple.com/library/content/releasenotes/MacOSX/WhatsNewInOSX/WhatsNewInOSX.html)
To download macOS High Sierra officially using **App Store.app** via macOS
```conf
https://itunes.apple.com/us/app/macos-high-sierra/id1246284741?mt=12
```
To download old versions of Apple Software, ie. iMovie
[support.apple.com/downloads](https://support.apple.com/downloads)
<a id="networking-in-macos"></a>
### Networking in macOS [🔝](#contents)
#### Setting up a NFS Server / Share in macOS High Sierra [🔝](#contents)
By default macOS has the NFS daemon disabled by default, but it can be enabled.
1. Make certain that SIP, ie. System Integrity Protection has been disabled.
2. Edit `/System/Library/LaunchDaemons/com.apple.nfsd.plist` to include the `-N` flag, so that non root users can mount **nfs** shares hosted on macOS.
3. Edit `/etc/exports` and include a path to a directory to be shared.
<strong>Ex</strong>
```conf
/Users/mr-fany/Movies/42 -ro -mapall=mr-fancy:mr-fancy -alldirs
```
The above example presently works on macOS 10.13.6 🤞
- With super user privileges load the above mentioned plist using **launchctl**
```shell
sudo -E launchctl -load /System/Library/LaunchDaemons/com.apple.nfsd.plist
````
To verify if the service was successfully loaded into launchd service manager with launchctl
```shell
sudo -E launchctl list | grep -i "nfsd"
```
The above command should list the process ID of **nfsd**
##### Troubleshooting nfsd, ie. a NFS Server on macOS [🔝](#contents)
To verify if the `/etc/exports` has properly been configured
```shell
nfsd checkexports
```
If there is an error the above mentioned file, nfsd will print the errors to STDOUT.
If **nfsd** needs to restarted, it can be restarted directly ie. launchctl is not required. 👍
```shell
nfsd restart
```
To get the status of **nfsd**
```shell
nfsd status
```
To display locally served file shares
```shell
showmount -e
```
To verify there are no syntax errors in the above mentioned **.plist** file
```shell
plutil -lint /System/Library/LaunchDaemons/com.apple.nfsd.plist
```
<a id="useful-resources-working-with-nfsd"></a>
##### Useful Resources for working with nfsd [🔝](#contents)
```shell
man nfs
man nfs.conf
man nfsd
man exports
```
```fish
ifconfig en0
```
#### macOS > nfs > Useful Links
- [cyberciti.biz > macOS working with nfs server & client](https://www.cyberciti.biz/faq/apple-mac-osx-nfs-mount-command-tutorial/)
<a id="ncurses"></a>
### ncures [🔝](#contents)
To print / show the current version of ncures installed on a system, ie. macOS
```shell
cat /usr/include/ncurses.h | grep -i "version"
```
<a id="working-with-openssh"></a>
### Working with OpenSSH [🔝](#contents)
When troubleshooting OpenSSH, and making changes to `~/.ssh/config` for particular host entries, neither the OpenSSH server or the current shell need to be restarted, ie. reinvoked as changes made to `~/.ssh/config` are reflected in realtime when using `ssh`.
For an incompetent guide comparing LibreSSL to OpenSSL, see [this](https://github.com/ipatch/re/wiki/ssl-battle)
To set up password less login, ie. public key authentication
```shell
cat ~/.ssh/id_rsa.pub | ssh -vvv -p [PORT_NUM] [user@[hostname] 'cat >> $HOME.ssh/authorized_keys && echo "Key copied"'
```
> If the `id_rsa.pub` file doesn't exists one can be generated using `ssh-keygen`
An alternative way to copy a public key from one host to another is using **ssh-copy-id**
```shell
ssh-copy-id [USER]@[HOSTNAME/IP].local -p[PORT]
```
> [USER] is the name of the $USER that will contain the public key to allow loggin in of the current $USER
<a id="working-with-ssh-agent"></a>
#### Working with ssh-agent [🔝](#contents)
**ssh-agent** is a utility app that allows the OS / user session to store unencrypted SSH keys in memory.
> The safest place to store unencrypted keys for SSH sessions would be in memory and **NOT** on disk.
<a id="working-with-brewed-openssh"></a>
### Working with brewed OpenSSH [🔝](#contents)
> First off, grab a cup of joe or tea if it is that time of the day for you because this isn't something that your gunna why to skim through, that said, if you have your cup of **covfefe** 🙄 and you're ready to roll 🚗
1. Download and install OpenSSH using homebrew
```shell
brew install openssh
```
> If you prefer to use **LibreSSL** over OpenSSL 🙋 then you're gunna wanna check out _no pun intended there_ the version of OpenSSH [I rolled](https://github.com/ipatch/homebrew-core/blob/master/Formula/openssh.rb) 🚬 for homebrew.
1. _1.1_ **optional**
```shell
brew install openssh --with-libressl
```
> **OpenSSH** does not need to be recompiled when upgrading **LibreSSL**, ie. I tested this when upgrading LibreSSL from 2.7.2 to 2.7.3 and running,
> `ssh -V`
>
> The output from the above command is
```shell
OpenSSH_7.7p1, LibreSSL 2.7.3
```
> However, the `sshd` service will need to be stopped and started because launchd doesn't have a "restart" feature per se on macOS in order for OpenSSH to load the new version of LibreSSL.
```shell
> launchctl unload homebrew.mxcl.sshd
> launchctl load homebrew.mxcl.sshd
```
> If using the Apple provided service of OpenSSH _which happens to be compiled with LibreSSL as well ...hmmm 🤔 wonder why that is_ then your first gunna wanna stop that launchd service, and unload it from launchd.
Recent version of macOS provide a nice little feature known as [SIP](https://en.wikipedia.org/wiki/System_Integrity_Protection) that supposedly prevents third parties 🙋 from modfying certain files and services. _thanks Obama_
> Personally, I disabled SIP on my local box a while ago because I like to pretend that I know what I'm doing when using "apps" such as DTrace.
- To stop the Apple provided OpenSSH daemon if it is currently running, and prevent it from launching in the [future](https://www.youtube.com/watch?v=Vm8S331kUPQ)
```shell
launchctl stop com.openssh.sshd
```
- To unload the service from launchd
```shell
sudo -E launchctl unload /System/Library/LaunchDaemons/ssh.plist
```
- To verify the service is stopped
```shell
lsof -i | grep "sshd"
```
...and you shouldn't 🙈 see anything printed to STDOUT if `sshd` isn't running.
- Copy or download my provided `sshd_config` along with my `com.chrisrjones.sshd.plist` from [this repo](https://github.com/ipatch/dotfiles/)
> Personally I keep those two files checked into my dotfiles repo, and symlink them to their respected locations on macOS, so I can preserve a copy of the files, and not have to modify / keep track of two separate files. 👍
```shell
curl https://raw.githubusercontent.com/ipatch/dotfiles/master/config/brew/macOS/Sierra/etc/ssh/sshd_config --output /usr/local/etc/ssh/sshd_config
```
```shell
curl https://raw.githubusercontent.com/ipatch/dotfiles/master/config/brew/macOS/Sierra/Library/LaunchDaemons/homebrew.mxcl.sshd.plist --output /Library/LaunchDaemons/com.chrisrjones.sshd.plist
```
- Create the respected log files and the PID for the OpenSSH service.
```shell
touch /usr/local/var/log/{sshd-error.log,sshd-out.log,sshd.log}
touch /usr/local/var/run/ssh/sshd.pid
```
- Next load the newly created `com.chrisrjones.sshd.plist` into launchd
```shell
sudo -E launchctl load -w /Library/LaunchDaemons/com.chrisrjones.sshd.plist
```
- **Cross fingers** 🤞 and if everything goes well you should be able to see your newly built and configured **sshd** server running with
```shell
ps aux | grep -i "sshd"
```
Pat yourself on the back if you made it this far and your server is up and running, and make sure to tip your DevOps engineer.
> because developers need heros too.
<a id="gotchas-working-with-brewed-openssh"></a>
#### Gotchas Working with brewed OpenSSH [🔝](#contents)
> Presently the OpenSSH provided by homebrew compiles with OpenSSL by default when installing 🙄 _boo_
The access list for allowing users who can login remotely using SSH is still maintained via **System Preferences...** > **Sharing** > **Remote Login** and toggling the users by adding their name to the **Only theses users:** list.
> In order to get **password** auth working with OpenSSH Server `UsePAM yes` must be set within the respected `sshd_config` file. Most recent build of OpenSSH 7.x > do not allow running `sshd` as a standard user, in short `sshd` needs to be run as the super user on the system, ie. `root` if on a UNIX based system. To aviod permission issues make sure the respected `ssh_host_{dsa_key,ecdsa_key,ed25519_key,rsa_key} files have a *root/wheel* ownership to avoid
```conf
debug1: setgroups() failed: Operation not permitted
```
```shell
launchctl list | grep "chrisrjones"
```
presently does not display the sshd service 🤷‍♂️
<a id="tshooting-working-with-brewed-openssh"></a>
#### Troubleshooting Working with brewed OpenSSH [🔝](#contents)
> I am [avaible](https://www.patreon.com/ipatch/) for children's birthday parties and bar mitzvahs.
If launchd runs into any errors with the provided plist file, when starting `sshd` it should dump the error messages into `/usr/local/var/log/sshd-error.log`.
If there is an issue with the OpenSSH server itself, ie. a bad configuration setting with the `sshd_config` the server should put the error message into `/usr/local/var/log/sshd.log`
Uncomment the `-d` flag in the above mentioned `.plist` file to start **sshd** in debug mode for more versobe troubleshooting.
> `-d` support the use of `-d` `-d` `-d`, ie. 3 levels of d's. When **sshd** is run in **debug** mode the server will stop running after the first disconnection.
<a id="todos-working-with-brewed-openssh"></a>
#### TODOs Working with brewed OpenSSH [🔝](#contents)
> With your newly aquired knowledge you should be able to setup `ssh-agent`.
- [x] ~~Setup ssh-agent to work with newly built OpenSSH server~~
- [ ] See if it's possible if the homebrewed version of OpenSSH server can play nice 👨 👧 👦 with macOS System Preferences. 🤔
<a id="setup-x11-forwarding-through-ssh"></a>
#### Setting Up X11 Forwarding through SSH [🔝](#contents)
> Native macOS apps won't run on \*nix because their not X11 apps, but rather their cocoa apps.
To allow for X11 forwarding through SSH, edit `sshd_config`
```conf
X11Forwarding yes
```
<a id="connecting-to-x11-server"></a>
##### Connecting to a X11 Server with X11 forwarding enabled [🔝](#contents)
```shell
ssh -Y [user]@[host]
```
<a id="useful-links-openssh"></a>
#### Useful Links OpenSSH [🔝](#contents)
- [coderwall.com _using SSH provided by homebrew_](https://coderwall.com/p/qdwcpg/using-the-latest-ssh-from-homebrew-on-osx)
<a id="working-with-locales-on-macOS"></a>
### Working with Locales on macOS [🔝](#contents)
To print the set locales on macOS
```shell
locale
```
<a id="working-with-users-and-groups"></a>
### macOS > Working with Users and Groups [🔝](#contents)
To list all users on a macOS
```shell
dscl . list /Users
```
To list all groups on a macOS
```shell
dscl . list /groups
```
To create, edit, update, or delete a _group_ on macOS from a CLI
> ⚠️ When managing groups from a CLI **System Preferences.app** will not update the **Users & Groups** pane with the updated data until the **System Preferences.app** is _closed_ and then reopened.
```shell
echo "macOS group editing syntax"
dseditgroup -p -o VERB "GROUP_NAME"
echo "macOS create group example"
dseditgroup -p -o create "mr-fancies"
echo "macOS delete group example"
dseditgroup -v -p -o delete -n /Local/Default "mr-fancies"
```
> An optional **-v** flag can be passed to print more verbose output to STDOUT
To add a user to a group on macOS, ie,
```shell
dseditgroup -v -p -o edit -a ipatch -t user wheel
```
To verify if a user is a member of a group on macOS
```shell
dseditgroup -o checkmember ntfsusers
```
To list all **users** of a particular group
```shell
dscacheutil -q group -a name [mr-fancy]
```
The above command should print all local users who belong to the group **mr-fancy**
To add a user to the system
```shell
sysadminctl -addUser [ipatch]
```
To print the **GID** **UID** **$HOME** directory, and **SHELL** for a specific user
```shell
dscacheutil -q user -a name mr-fancy
```
❗️ If only the **UID** of the user is known but not the name of the _user_ then try the below example
```shell
dscacheutil -q user -a uid 42
```
To change the **UID** for **mr-fancy** on macOS using a CLI
```shell
dscl . -change /Users/mr-fancy UniqueID 42 4242
echo "❗️ chage the Users $HOME dir so they have access to it"
chown -R 4242 /Users/pi
```
To rename a user from the **System Preferences** using the Cocoa GUI [see](https://support.apple.com/en-us/HT201548)
<a id="useful-links-working-with-users-and-groups"></a>
#### Useful Links working with users and groups [🔝](#contents)
- [macOS add user via CLI](http://smallbusiness.chron.com/add-user-terminal-mac-os-x-screen-sharing-31846.html)
- [StackOverflow - set up `/home`](https://stackoverflow.com/a/25558272/708807)
<a id="image-processing"></a>
### Image Processing [🔝](#contents)
To take a screen capture using a GUI on macOS use **Grab**
> **Grab** is able to take a screen capture including the mouse cursor.
<a id="useful-links-image-processing"></a>
#### Useful Links Image Processing [🔝](#contents)
- [**StackExchange** combine images](https://apple.stackexchange.com/a/52882/43460)
- [**StackExchange** VLC media user](https://apple.stackexchange.com/a/317474/43460)
<a id="working-with-x11-on-macos"></a>
### Working with X11 on macOS [🔝](#contents)
To install **X11** windowing manager on macOS using brew
```shell
brew cask install xquartz
```
To prevent **X11**, ie. **XQuartz.app** from polluting the $HOME dir with **.serverauth.\*** files
1. Edit **/opt/X11/bin/startx**
2. Change
```conf
xserverauthfile=$HOME/.serverauth.$$
```
to
```config
xserverauthfile=$XAUTHORITY
```
[**Credit**](https://unix.stackexchange.com/a/199171/33002)
<a name="xcode"></a>
### Xcode [🔝](#contents)
To install Xcode Command Line Tools
```shell
xcode-select --install
```
>**Install Command Line Developer Tools.app** can be located within `/System/Library/CoreServices`
The command line developer tools, ie. `clang` are located in as of macOS 10.13.x with Xcode 9.4 installed.
```shell
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/
```
To display all the Xcode SDKs installed on a system
```shell
xcodebuild -showsdks
```
To purge old symbol files for unused versions iOS used by Xcode iOS version [X.X.X] can be deleted from
```conf
$USER/Developer/Xcode/iOS DeviceSupport/[MAJOR.MINOR.PATCH]
```
#### Working with Xcode from the command line [🔝](#contents)
macOS 10.13 High Sierra, file tagging using color labels appears to be broken. [see](https://discussions.apple.com/thread/8232839)
To compile an [Objective-C](https://en.wikipedia.org/wiki/Objective-C) file from the CLI on macOS, use **xcrun**
```shell
xcrun clang /path/to/mr-fancy-42.m -c
```
> The above will only create an object file ie. **.o** of the hello world source file wrtiten in ojbc
To compile a Swift source file using the Xcode toolchain from the CLI on macOS, use **xcrun**
```shell
xcrun swiftc -c /path/to/mr-fancy-42.swift
```
To compile a binary that can be run from the CLI using **./path/to/hello-world-objc**
```shell
clang -x objective-c -framework Foundation hello-world.m
```
> The above command will create an intermediate object file within the directory that the source file, ie. `hello-world.m` resides. The **-x** flag explicity tells **clang** the source file is an **Objective-C** source file.
To syntax check a source file that can be compiled with **clang** use the **-fsyntax-only** flag
```conf
-fsyntax-only
```
<a id="working-with-files-in-finder"></a>
### Working with files in Finder [🔝](#contents)
###### #Finder #HideAllWindows #HideAllApplications #macOS #OnlyShowDesktop #DisplayDesktop
To toggle the visibility 🙈 of hidden files in macOS >= Sierra
<kbd></kbd>+<kbd>shift</kbd>+<kbd>.</kbd>
A workflow for for hiding all windows including **Finder** ie. to only show the desktop is to
1. Make sure the **Finder.app** is in focus ie. the Finder menu bar is presented
2. **Hide Others** <kbd></kbd> + <kbd></kbd> + <kbd>h</kbd>
a. One all other application windows have been hidden but the finder window.
3. Close the active finder window, or even _Quit_ the **Finder.app**
a. Then there shouldn't be any application windows visible.
> See notes contained within this document for allowing to _Quit_ **Finder**
To hide all icons on the desktop
```shell
defaults write com.apple.finder CreateDesktop -bool false
killall Finder
```
To show all files & folders including hidden files and folders in macOS Finder
```shell
defualts wirte com.apple.finder AppleShowAllFiles TRUE
killall Finder
```
> ⚠️ on MacOS >= Sierra `.DS_Store` files are still hidden from Finder when setting `AppleShowAllFiles` `TRUE`
To show Finder command variables
```shell
defaults read com.apple.Finder
```
To prevent writing `.DS_Store` files to network shares
```shell
defaults write com.apple.desktopservices DSDontWriteNetworkStores TRUE
```
To show a specific setting for a Finder variable
```shell
defaults read com.apple.Finder AppleShowAllFiles
```
To show full path in Finder windows
```shell
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true; killall Finder
```
To allow text selection in Quick Look
```shell
defaults write com.apple.finder QLEnableTextSelection -bool true
```
<a id="working-with-prefrencepances"></a>
### Working with PreferencePanes [🔝](#contents)
Custom installed **Preference Panes** on macOS 10.13.x are located within `/Library/PrefrencePanes/`
> Try and avoid putting custom **Preference Panes** within `/System/Library/PreferencePanes` because macOS does not like 3rd party files in that location. The above mentioned directory is `755` with `root` owner and `wheel` group perms by default.
**IMHO** I put my daily driver user `echo (whoami)` in the **wheel** group and set the permissions to `775`, so my `$USER` could create custom `PreferencePanes` if needed.
<a id="working-with-files-via-cli"></a>
### Working with files via CLI [🔝](#contents)
To delete all `.DS_Store` files in the current working directory & and all sub directories recursively
```shell
find . -name '.DS_Store' -delete
```
<a id="tweaking-macos-settings"></a>
### Tweaking macOS settings [🔝](#contents)
> ❗️ **tags** macOS osx os x settings setting customize
To disable app icons from bouncing in the **dock**
```shell
defaults write com.apple.dock no-bouncing -bool TRUE
killall Finder
echo "inverse `TRUE` to reenable dock bounce"
```
macOS menu bar icon entries located in the following path
```conf
/System/Library/CoreServices/Menu Extras
```
<strong>Ex</strong>
```conf
/System/Library/CoreServices/Menu Extras/Volume.menu
```
To automatically reopen windows for an application after it has been closed on macOS
```conf
 → System Preferences... → General
```
![restore-app-windows-macOS](https://raw.githubusercontent.com/wiki/ipatch/dotfiles/lib/restore-app-windows.png)
<a id="tweaking-macOS-settings-from-the-cli"></a>
#### Tweaking macOS settings from the CLI [🔝](#contents)
To check and verify if **[SIP](https://en.wikipedia.org/wiki/System_Integrity_Protection)** is enabled
```shell
csrutil status
```
To disable the macOS boot chime
```shell
nvram SystemAudioVolume=" "
```
To always boot macOS in verbose mode, ie. typically how a GNU/Linux displays boot messages when booting
```shell
sudo nvram boot-args="-v"
```
To disable **boot-args** ie. change macOS from booting verbosely
```shell
sudo nvram boot-args=
```
To check and see if verbose booting is enabled on macOS
```shell
nvram -p | grep -i "boot-args"
```
To always have the save dialog / panel expanded
```shell
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
```
To automatically illuminate built-in MacBook keyboard in low light
```shell
defaults write com.apple.BezelServices kDim -bool true
```
To turn off keyboard illumination when computer is not used for 5 minutes
```shell
defaults write com.apple.BezelServices kDimTime -int 300
```
To disable shadow in screenshots
```shell
defaults write com.apple.screencapture disable-shadow -bool true
```
> When editing system settings using **defaults write** settings for $USER are stored in /Users/$USER/Library/Preferences as a Apple binary Plist file.
<a id="macos-automating-cli-tasks"></a>
### macOS Automating CLI tasks [🔝](#contents)
The below directories run commands automatically
```conf
/etc/periodic/daily
/etc/periodic/weekly
/etc/periodic/monthly
```
To run the **periodic** scripts in macOS
```shell
periodic daily weekly monthly
```
<a id="macos-automating-tasks-on-sierra"></a>
#### macOS Automating tasks on macOS >= Sierra [🔝](#contents)
<a id="general-launchd-commands"></a>
##### General launchd commands [🔝](#contents)
The preferred way to load a launchd services
```shell
launchctl bootstrap gui/[USER_ID] ~/Library/LaunchAgents/com.domain.service-name.plist
```
The preferred way to unload a launchd service
```shell
launchctl bootout gui/[USER_ID] ~/Library/LaunchAgents/com.domain.service-name.plist
```
To find the user id for a the current `$USER` operating the `$SHELL`
```shell
id -u
```
<a id="setting-up-a-launchd-service"></a>
##### Setting up a launchd service [🔝](#contents)
> macOS does not support automating tasking using `cron` anymore. The preferred way is to use `launchd` to load a `.plist` file.
- Create a `com.chrisrjones.mr-fancy-task.plist` file within,
```conf
$HOME/Library/LaunchAgents/
```
- Generate a `.plist` file via [this](http://launched.zerowidth.com)
- Load the `.plist` file via
```shell
launchctl load -w ~/Library/LaunchAgents/com.chrisrjones.mr-fancy-task.plist
```
<a id="useful-links-macos-automating-tasks"></a>
##### Useful Links macOS Automating tasks [🔝](#contents)
- [Web Interface for generating `.plist` launchd tasks](http://launched.zerowidth.com/)
<a id="working-with-audio-on-macOS"></a>
### Working with Audio on macOS [🔝](#contents)
To determine the value of `SystemAudioVolume`
```shell
nvram SystemAudioVolume
```
<a id="working-with-power-management-on-macos"></a>
### Working with Power Management on macOS [🔝](#contents)
To check the remaining time the system can run on battery power
```shell
pmset -g batt
```
To get an approximate time of how long a macOS system has been running on battery 🔋 power see **Activity Monitor.app**
To display all settings related to power management on macOS
```shell
pmset -g
```
#### Experimenting power management settings on macOS [🔝](#contents)
To change the **standbydelay** time on macOS using **pmset**
```shell
sudo pmset -a standbydelay [INTEGER]
```
The above integer is in **milliseconds**
<strong>Ex</strong>
To set the **standbydelay** time on macOS for 12 hours
```shell
sudo pmset -a standbydelay 43200000
```
To disable **standby** ie. deep sleep on macOS
```shell
sudo pmset -a standby 0
```
<a id="working-with-disk-images"></a>
### Working with Disk Images [🔝](#contents)
To convert an ISO file system to a macOS image file
```shell
hdiutil convert /path/to/ISO -format UDRW -o /path/to/destination
```
To create an ISO to be burnt as a data DVD for PC and MAC
```shell
mkisofs -J -r -o myimage.iso data_dir
```
> `mkisofs` is not native on macOS 10.12.x
To copy the contents of an ISO to a USB drive
```shell
dd if=/path/to/myISO.iso of=/dev/myUSB bs=1m
```
#### Creating a Bootable Windows 10 USB Install Drive for Intel Macs [🔝](#contents)
- **Rufus** can be used to create a bootable USB Windows 10 install disk. Rufus provides options to create a bootable USB for both BIOS and UEFI systems. 👍
The quickest and most painless way of creating a bootable Windows 10 USB drive on macOS is to use **Boot Camp Assistant** provided by Apple.
> 🚨 A bootable Windows 10 USB Install drive created with **Boot Camp Assistant** will only work with a Intel Mac, ie. modern MacBook Pro, and **will not** work with other UEFI laptops! **Etcher.app** will NOT be able to create a bootable Windows 10 USB drive. 😩
<a id="troubleshooting-modern-intel-mac-hardware"></a>
### Troubleshooting modern Intel Mac hardware [🔝](#contents)
> **SMC** a Intel Mac controls the the power management features of a Mac.
To reset **SMC** on an Intel Mac without a touch bar
1. Press and hold <kbd>shift</kbd> + <kbd>control</kbd> + <kbd>option</kbd>
2. Keep the keys pressed for 10 seconds while holding the power button.
3. Release the power button along with the three keys
4. Then press the power button again to turn on the computer.
To check and see if the EFI on a Intel Mac is 32bit or 64 bit
```shell
ioreg -l -p IODeviceTree | grep firmware-abi
```
The output from the above command should either ouput **"EFI64"** or **"EFI32"**
To boot an Intel Mac, ie. a modern MacBook Pro, ie. 8,2 version into single-user mode.
<kbd></kbd>+<kbd>s</kbd> after booting up the computer, and shortly after hearing the Mac boot chime.
To reset the NVRAM on a modern MacBook
<kbd></kbd>+<kbd>option</kbd>+<kbd>p</kbd>+<kbd>r</kbd>
To check and see if an Intel Mac is using a 32 or 64 bit UEFI system
```shell
ioreg -l -p IODeviceTree | grep firmware-abi
```
The above command 👆 should either print **EFI64** or **EFI32**
To boot an Intel Mac into Internet Recovery Mode
<kbd>option</kbd>+<kbd></kbd>+<kbd>R</kbd> or <kbd>shift</kbd>+<kbd>option</kbd>+<kbd></kbd>+<kbd>R</kbd>
To boot an Intel Mac into **Apple Diagnostic/Hardware Test** mode
1. Turn the computer completely off
2. Hold <kbd>option</kbd>+<kbd>D</kbd> after the startup chime, select the appropiate WIFI network, and then the Mac should download the appropiate **Apple Diagnosit/Hardware Test** for the Mac.
> Apple changed the **Apple Diagnostic/Hardware Test** program some time around 2013, and Macs prior to 2013 user an older blue GUI version of the test.
<a id="working-with-filesystems"></a>
### Working with file systems and disks, ie. storage devices [🔝](#contents)
To securely wipe a partition on a disk, ie. storage medium
```shell
/path/to/shred --verbose --random-source=/dev/urandom -n1 /dev/disk[Number]s[Partition]
```
A quick way to list the file system, ie. **HFS+** for a particular mount point
```shell
diskutil info -all
```
or
```shell
diskutil list
```
To display / show all file systems accessible to a macOS system
```shell
mount
```
> No flags or arguments are required to display the currently mounted file systems on macOS, and the above command should the mounted disks, ie. a removable USB drive and their respected file systems accessible to macOS.
To unmount a file system on macOS
```shell
diskutil unmountDisk /path/to/disk
```
> The above command will unmount all volumes associated with a disk.
<strong>Ex</strong>
```shell
diskutil unmountDisk /dev/disk2
```
To quick and dirty way to see the type of partition table a disk using on macOS
```shell
diskutil list
```
> The above command should 99% of the time list volume 0 as either **GUID_partition_scheme** or **FDISK_partition_scheme**
<strong>Ex</strong>
```conf
/dev/disk3 (external, physical):
0: GUID_partition_shceme
```
To format a file system on macOS with a specific format
```shell
newfs_* -F /path/to/device
```
To format a USB disk with a MSDOS FAT 16 file system on macOS
<strong>Ex</strong>
```shell
newfs_msdos -v "MR_FANCY_VOLUME" -F 16 /dev/disk2
```
> BSD derivatives of UNIX use **newfs_[FS_TYPE]** to where as GNU derivatives use **mkfs.[FS_TYPE]**
On macOS an alternative way to format a disk is to use **diskutil**
<strong>Ex</strong>
```shell
diskutil eraseDisk "MS-DOS FAT16" MR_FANCY_DISK_NAME /dev/disk2
```
To copy / _burn_ the contents of an ISO image to a USB drive or other removable storage
```shell
sudo dd if=/path/to/mr-fancy-42.iso of=/dev/disk[NUMBER]
```
> **sudo** will be required to write to block level device
**Protip** to print a status of the transfer on macOS
<kbd>control</kbd>+<kbd>shift</kbd>+<kbd>T</kbd>
To display an active progress bar when using a command such as **dd** use **pv**
```shell
pv /path/to/mr-fancy-42.iso | sudo dd of=/dev/disk[NUMBER]
```
<a id="working-with-fat32-file-systems"></a>
#### Working with FAT-32 file systems [🔝](#contents)
To the best of my knowledge the largest file a FAT-32 file system can store is 4GB.
To mount a FAT[16-32] file system on macOS using **diskutility**
```shell
diskutil mount /path/to/blockDevice
```
<strong>Ex</strong>
```shell
diskutil mount /dev/disk3s2
```
> The above command will mount the file system within the **/Volumes** directory on the local macOS system with the respected volume label as the mount point.
To unmount a volume / partition on macOS with FAT[16-32] file system.
```shell
diskutil umount /path/to/mount/point
```
> The path to the block device can also be specified.
##### Working with large files on a FAT-32 file system [🔝](#contents)
To split a **really** large file into chunks 🤮 that can be copied to a **FAT-32** file system
```shell
rar a -v4G /path/to/mr-fancy-42-universe.rar /path/to/mr-fancy-42-universe.qcow2
```
An alternative to using **rar** is using **GNU Core Utilites** to split the file using the aptly named **split** command.
```shell
split --bytes=3500M /path/to/mr-fancy-42-universe.qcow2 /path/to/output/splits/mr-fancy-42-universe.qcow2
```
> When using the **split** command, specifying **-bytes=4G** will create files too large for a FAT32 file system.
###### Transferring large files to a FAT-32 file system [🔝](#contents)
**cp** is great for copying files, however it lacks any sort of progress bar, but there are various bolt-on 🔩 solutions, ie. piping through **pv** or using some form of python, but from my personal expierence **rsync** is the best solution for transferring large files.
```shell
rsync -ah --progress /path/to/mr-fancy-42-universe.qcow2 /path/to/external/media/fat32/mr-fancy-42-universe.qcow2
```
> **-a** will preserve file permissions 👍 _FAT32 doesn't support permissions though_
> **-h** will make the progres bar in human readable output
> **--progress** will transfer the file will outputting the progress to STDOUT
<a id="building-grub-on-macos-from-source"></a>
### Building GNU GRUB v2 on macOS from source [🔝](#contents)
- Clone the grub source
```shell
git clone git://git.savannah.gnu.org/grub.git
```
- Clone **objconv** from GitHub
```shell
git clone git@github.com:vertis/objconv.git
```
> GRUB will not compile using Xcode tooling out of the box, thus the dependency for **objconv**
- Build **objconv**
```shell
g++ -o objconv -O2 src/*.cpp
```
- Put **objconv** in the `$PATH`
- Build GRUB to support **x86_64** and **efi**
```shell
cd /path/to/src/grub
mkdir grub-build
../configure --prefix=/path/to/put/the/grub/binary --target=x86_64 --with-platform=efi
make
make install
```
> **make** should be run the **grub-build** dir and **NOT** the grub git source project root.
- **Optional** Specify a font to use with GRUB, on macOS most system fonts can be found in **/Library/Fonts**, that said, choose a **.ttf** font for the below command.
```shell
/path/to/grub-mkfont -o share/grub/unicode.pf2 /Library/Fonts/Times\ New\ Roman.ttf
```
- Create a **build** dir preferably in the git source root for building a self contained GRUB binary to work with a UEFI system, ie. a MacBook
```shell
cd /path/to/grub/git/src
mkdir build
```
- Create a **grub.cfg** file, and put the following lines within the file
```shell
insmod part_msdos
set root=(hd0,msdos1)
```
- Build a standalone GRUB binary to bootstrap an ISO, ie. an install media from a USB drive.
```shell
/path/to/bin/grub-mkstandalone -O x86_64-efi -o BOOTX64.EFI "boot/grub/grub.cfg=build/grub.cfg"
```
If all goes well there should be a **BOOTX64.EFI** file within the **build/** directory.
<a id="install-grub-on-a-removable-usb-drive"></a>
#### Install GRUB on a removable USB drive [🔝](#contents)
To install the GRUB bootloader on a removable USB drive using macOS
```shell
grub-install -v --target=x86_64-efi --efi-directory=/mnt/[USB-DRIVE-LABEL] --boot-directory=/Volumes/[USB-DRIVE-LABEL]/boot --removable --bootloader-id=grub
```
> The above command will not succeed on a removable USB drive if **--removable** is omitted from the command. If the above command succeeds the following message will output to STDOUT
```conf
Installation finished. No error reported
```
##### grub-install alternative [🔝](#contents)
To install grub on a GPT formatted removable USB disk using macOS a couple of steps will need to be performed
- Verify the disk has been formatted with a GPT parititon table, and **not** an MBR partition table.
```shell
diskutil list
```
- set a path to where the EFI partition can be mounted, and you have read/write access to the path.
<strong>Ex</strong>
```shell
mkdir /mnt/usb-gpt-efi
sudo chown -R $USER:wheel /mnt/usb-gpt-efi
```
> If the above directory is created within the `/Volumes` directory then the mount point, ie. directory that holds the mounted file system will be deleted.
- mount the **EFI** partition of the USB disk
```shell
sudo mount -t msdos /dev/disk3s1 /Volumes/usb-gpt-efi
```
- Verify the partition has properly been mounted.
```shell
mount
```
- Install GRUB boot loader to the USB drive to work with a **UEFI** system / boot rom.
```shell
grub-install -v --target=x86_64-efi --efi-directory=/Volumes/usb-gpt-efi --boot-directory=/Volumes/grub-for-mac/boot --removable --bootloader-id=grub
```
<a id="macos-and-grub-useful-links"></a>
#### macOS and GRUB Useful Links [🔝](#contents)
- [refind](http://www.rodsbooks.com/refind/)
> **refind** is the successor to [refit](http://refit.sourceforge.net/)
<a id="working-with-the-bless-command-on-macos"></a>
#### Working with the bless command on macOS [🔝](#contents)
In order to boot from a removable media, ie. a USB flash drive on macOS a drive or Volume needs to blessed, using the native **bless** command from macOS or using the **hfs-bless** provided by mactel linux.
To see / print the currently **blessed** disk that will boot macOS
```shell
bless -getBoot
```
<a id="working-with-automountd"></a>
#### Working with automountd [🔝](#contents)
**automountd** is a service provided by macOS that can automount file systems, disks, local & remote, ie. across the network.
The configuration files for **automountd**
```conf
/etc/autofs.conf
/etc/auto_master
/etc/auto_resources
```
To show the file systems / partitions that have been automatically mounted
```shell
automount -v
```
If a change is made to one of the above files, the cache needs to be flushed
```shell
automount -cv
```
Some useful man pages include
```shell
man automount
man automountd
man auto_master
man autofs.conf
```
<a id="benchmarking-hdd-performance"></a>
#### Benchmarking HDD performance [🔝](#contents)
To test HDD performance on a macOS / Linux system, [see](https://www.cyberciti.biz/faq/howto-linux-unix-test-disk-performance-with-dd-command/)
A general universal command to test read / write performance to a storage media
```shell
time sh -c "dd if=/dev/zero of=/tmp/testfile bs=100k count=1k && sync"
```
> Results running macOS 10.12.6 with a HFS+ filesystem on a 1TB Samsung SSD
```conf
╭─capin at rogue in /opt/Code/dotfiles (master ✔)
╰─λ time sh -c "dd if=/dev/zero of=/tmp/testfile bs=100k count=1k && sync"
1024+0 records in
1024+0 records out
104857600 bytes transferred in 0.212054 secs (494485334 bytes/sec)
0.34 real 0.00 user 0.16 sys
╭─capin at rogue in /opt/Code/dotfiles (master ✔)
╰─λ ls -lah /tmp/testfile
-rw-r--r-- 1 capin wheel 100M May 19 20:24 /tmp/testfile
╭─capin at rogue in /opt/Code/dotfiles (master ✔)
╰─λ time sh -c "dd if=/dev/zero of=/tmp/testfile2 bs=100k count=1k && sync"
1024+0 records in
1024+0 records out
104857600 bytes transferred in 0.086153 secs (1217108667 bytes/sec)
0.20 real 0.00 user 0.12 sys
╭─capin at rogue in /opt/Code/dotfiles (master ✔)
╰─λ time sh -c "dd if=/dev/zero of=/tmp/testfile3 bs=100k count=1k && sync"
1024+0 records in
1024+0 records out
104857600 bytes transferred in 0.299482 secs (350129766 bytes/sec)
0.49 real 0.00 user 0.18 sys
```
<a id="building-macos-install-boot-media"></a>
### Building macOS install / boot media [🔝](#contents)
To create a bootable macOS High Sierra install media on a removable USB disk drive.
> Make sure `Install macOS High Sierra.app` has been downloaded from the App Store.
```shell
sudo /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/createinstall \
--volume /Volumes/Install-macOS-High-Sierra \
--applicationpath /Application/Install\ macOS\ High\ Sierra.app
```
To create a bootable macOS Mavericks install media _USB_
```shell
sudo /Applications/Install\ OS\ X\ Mavericks.app/Contents/Resources/createinstallmedia \
--volume /Volumes/<MEDIA> \
--applicationpath /Applications/Install\ OS\ X\ Mavericks.app --nointeraction
```
### Building a USB drive / install media for an Intel Mac with GRUB [🔝](#contents)
<strong>directory layout</strong>
```conf
EFI
debian
grubx64.ef
mach_kernel
System
Library
CoreServices
boot.efi
SystemVersion.plist
.VolumeIcon.icns
```
The contents of the **SystemVersion.plist** file will roughly look like the following
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ProductBuildVersion</key>
<string></string>
<key>ProductName</key>
<string>GNU+Linux</string>
<key>ProductVersion</key>
<string>GRUB V2</string>
</dict>
</plist>
```
<a id="disk-management"></a>
### Disk Management [🔝](#contents)
To enable **Debug** mode for **Disk Utility.app**
```shell
defaults write com.apple.DiskUtility DUDebugMenuEnabled 1
```
> The above command may not be applicable for macOS High Sierra as **Disk Utility** by default can show all partitions.
To list the supported file systems a disk can formatted with
```shell
diskutil listFilesystems
```
To list the available disks attached to the system
```shell
diskutil list
```
To erase a **Volume** using `diskutil` and not allocate the _free space_ with a partition.
```shell
diskutil eraseVolume free %noformat% [IDENTIFIER]
```
> [IDENTIFIER] can be printed using `diskutil list`
To erase an entire disk and not just a partition / volume on a disk and allocate with _free space_
```shell
diskutil eraseDisk free %noformat% [IDENTIFIER]
```
> The [IDENTIFIER] can be obtained with `diskutil list`, and verified with the **/dev/disk[NUMBER]**, also using the above command will format the disk with a GUID partition map, ie. known as a **Scheme** in the macOS world.
<strong>Ex</strong>
```shell
diskutil list
```
<strong>Output</strong>
```conf
/dev/disk3 (external, physical):
...
```
To resize a partition for a particular disk, ie. a USB flash drive using **diskutil** on macOS, use the **eraseDisk** in conjunction with the **resizeVolume** command.
> From my empirical evidence (could be wrong on this assessment) using diskUtil on macOS it's not possible to create a partition with a specific size from a **free space** drive using **diskUtil** on macOS. The reason for this is because there are **no** logical volumes, ie. partitions on the disk, that said, that's why the simplest solution I found was to create a **JHFS+** partition that can be resized at later date and time.
1. Create a JHFS+ partition that occupies all free / empty space for a disk.
```shell
diskutil eraseDisk JHFS+ grub-for-mac /dev/disk3
```
> About the above command, **eraseDisk** will nuke 🤯 the entire disk ie. removing all data from it, **grub-for-mac** will be the **volume label** for the disk, and **/dev/disk3** specifies the path to the disk to put the **JHFS** file system and partition on.
- Validate the disk is properly partitioned and formatted.
```shell
diskutil list
```
> Should see ~ 3 partitions indexed at 0
1. GUID_partition_scheme
2. EFI
3. Apple_HFS
- Next resize the JHFS+ partition to a smaller size
```shell
diskutil resizeVolume /dev/disk3s2 512M
```
> To get an idea of what size a file system on a partition / logical volume can be
```shell
diskutil resizeVolume /dev/disk3s2 limits
```
There now should be a partition on the removable USB disk that is ~ 512MB in size and formatted with a JHFS+ file system.
To create an additional partition on the above mentioned disk with a 512MB JHFS+ partition use an external program named **gdisk**.
1. **gdisk** can be easily obtained if [Homebrew](brew.sh) is installed.
```shell
brew cask install gdisk
```
> ⚠ To modify any attributes associated with a disk **gdisk** needs be launched with super user privileges.
- Launch **gdisk**
```shell
sudo gdisk
```
- Specify path to disk
```conf
/dev/disk[NUMBER]
```
- Create a partition with they type hex code of **0700** so a FAT file system can be formatted to the partition.
> To create a partition with a specific size using **gdisk** ie. create a 5GB on a 32GB disk use `+5G`
- Format the newly created partition with a **FAT-32** file system
```shell
diskutil eraseVolume FAT32 [VOLUME_NAME] /dev/disk[ID_PARTITION_NUMBER]
```
To erase a disk and format with a particular file system
> diskutil eraseDisk [fileSystem] [label / name] [/path/to/disk]
<strong>Ex</strong>
```shell
diskutil eraseDisk fuse-ext2 samsung-1tb /dev/disk2
```
To create Linux compatible file system for a particular partition on a disk
```conf
/opt/gnu/sbin/mkfs.ext2 /dev/disk2s2
```
> 🚨 The above mentioned command will create a **ext2** formatted filesystem. If you'd prefer to use an **ext4** filesystem, use **mkfs.ext4** instead. Also **mkfs.ext2** requires tools to be properly installed and setup on macOS in order to format a disk with a **ext{2,3,4}** file system.
To disable / turn off journaling for a **hfs+** disk
```shell
sudo diskutil disableJournal /Volumes/mr-fancy-disk-label
```
<a id="working-with-fuse-ext2"></a>
#### Working with [fuse-ext2](https://github.com/alperakcan/fuse-ext2) [🔝](#contents)
To mount an external disk with an ext{2,3,4} file system using **fuse-ext2**
```diff
- sudo -E mount -t fuse-ext2 /path/to/external/disk/partition /path/to/fancy/mnount/point
+ sudo fuse-ext2 /path/to/block/device/partition /path/to/mount/point -o rw+,allow_other,uid=[INT],gid=[INT]
```
<strong>Ex</strong>
```shell
sudo fuse-ext2 /dev/disk2s2 ~/mnt/sdcard -o rw+,allow_other,uid=501,gid=20
```
> `sudo` must be used to mount the file system.
To verify if the file system successfully mounted using **FUSE for macOS**
```shell
mount
```
> The above command will display all locally mounted file systems.
To unmount a fuse-ext2 file system
```shell
sudo -E unmount /full/path/to/mount/point
```
#### fuse-ext2 Gotchas [🔝](#contents)
When working with fuse-ext2 to mount ext{2,3,4} file systems, presently `sudo` is required to mount a file system _boo_. In order to mount a file system and to allow access for a particular user on the system
```shell
sudo -E fuse-ext2 /path/to/disk/s[num] /path/to/mount/point -o rw+,allow_other,uid=[num],gid=[num]
```
<strong>Ex</strong>
```shell
sudo -E fuse-ext2 /dev/disk2s2 ~/mnt/ext-m2-1tb -o rw+,allow_other,uid=501,gid=20
```
<a id="useful-links-disk-management"></a>
#### Useful Links Disk Management [🔝](#contents)
- [Using the Mac OS X automounter](https://useyourloaf.com/blog/using-the-mac-os-x-automounter/)
- [superuser.com - _automount **ext** fs_](https://superuser.com/questions/1299736/how-to-automount-an-ext-filesystem-in-macos)
- [Linux - automounting a drive](https://linuxconfig.org/automatically-mount-usb-external-drive-with-autofs)
<a id="working-with-java"></a>
### Working with Java [🔝](#contents)
To completely remove / uninstall Java JRE and JDK
```shell
rm -rf /Library/Java/JavaVirtualMachines/jdk<version>.jdk
rm -rf /Library/PreferencePanes/JavaControlPanel.prefPane
rm -rf /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
rm -rf /Library/LaunchAgents/com.oracle.java.Java-Updater.plist
rm -rf /Library/LaunchDaemons/com.oracle.java.Helper-Tool.plist
rm -rf /Library/Preferences/com.oracle.java.Helper-Tool.plist
```
To completely remove Android Studio, see [this](https://stackoverflow.com/a/18458893/708807)
<!-- https://git.io/vxpPH -->
<a id="microsft-silverlight-on-macos"></a>
### Microsoft Silverlight on macOS
To remove / uninstall Silverlight on macOS, perform a search using GNU **find** or **locate** and manually remove all files.
<strong>Ex</strong>
```shell
find / -iname "*silverlight*" -type f 2>/dev/null
```
<a id="working-with-launchd"></a>
### Working with launchd [🔝](#contents)
<strong>TL;DR</strong>
- working with launchd / launchctl is a total pain the ass, that said, tip 💵 your dev ops engineers next time you see them.
- when loading or unloading a launchd service, ie. a **.plist** file within **$HOME/Library/LaunchAgents** refer to the **.plist** file, ie.
```shell
launchctl [load/unload] $HOME/Library/LaunchAgents/mr-fancy.plist
```
...and **NOT** the **<key>Label</key>** in the **.plist** file.
- when testing a launchd service refer to the value in **<string>** defined below the **<key>Label</key>** within the **.plist**, ie.
```shell
launchctl list com.example.mr-fancy-42-service
```
- if **StandardErrorPath** & **StandardOutPath** or defined in the **.plist** file / service, launchd should create the files if not created yet, _NOTE_ double check permissions of directory where files will be written.
- launchd should append to the files defined by **StandardErrorPath** & **StandardOutPath** and not overwrite them each time the service is started. 👌
To get a frame of reference on how launchd service files, ie. **.plist** files can be written, see **/System/Library/Launch{Angents,Daemons}**
> From all my empirical evidence, environment variables can not be set within the **StandardOutPath** or the **StandardErrorPath**
<a id="launchd-general-notes"></a>
#### launchd General Notes [🔝](#contents)
A **daemon** is a program that runs in the background as part of the overall system (that is, it is not tied to a particular user). A daemon cannot display any GUI; more specifically, it is not allowed to connect to the window server.
An **agent** is a process that runs in the background on behalf of a particular user. Agents are useful because they can do things that daemons can't, like reliably access the user's home directory or connect to the window server.
> If a launchd service / `.plist` file calls / runs a shell script one can verify the the shell script contains no errors by passing the `-n` flag as an arugument to the shell script, ie.
```shell
sh -n mr_fancy_shell_script.sh
```
If the above command does not print any output in the terminal then their aren't any syntax errors using that particular shell interpreter.
To test / lint a `.plist` file for syntax errors
```shell
plutil -lint $HOME/Library/LaunchAgents/com.mr-fancy.plist
```
To manually / arbitrarily start a launchd service / .plist
```diff
- launchd start $HOME/Library/LaunchAgents/com.mr-fancy.plist
```
To start a launchd service as a specific user via a `.plist` file
```xml
<key>UserName</key>
<string>mr-fancy-user</string>
```
<a id="working-with-environment-variables-in-launchd"></a>
#### Working with Environment Variables in Launchd [🔝](#contents)
To create an environment variable in launchd add the below to the respected **.plist** file.
```diff
-<array>
- <string>/bin/launchctl</string>
- <string>setenv</string>
- <string>MR_FANCY</string>
- <string>42</string>
-</array>
+<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin</string>
</dict>
```
To create a launchd variable from the command line
```shell
launchctl setenv FOO "BAR"
```
> `echo $FOO` will output **BAR**
To create a environment variable in a **.plist**
```xml
<string>launchctl setenv FOO "BAR"</string>
<string>launchctl setenv USER "${USER}";</string>
```
<a id="launchd-gotchas"></a>
#### launchd Gotchas [🔝](#contents)
> launchd `.plist` files can contain **spaces** in `<string>` values, ie.
```xml
<string>/Mr Super/fancy/path/to/special.plist</string>
```
When working with launchd services, **MAKE** sure to `remove` the service if it is no longer required to use it, ie.
```shell
launchctl remove com.github.asdf-vm.plist
```
...otherwise the service will remain loaded even if the env var is manually removed, and the service is `stopped` or `unloaded` 😡
To get a human readable explanation of a launchd error code, ie. `127`
```fish
launchctl error 127
```
When creating a **launchd** service at a system level, ie. putting a service file in `/Library/LaunchDaemons/`, running
```shell
lc list | grep `chrisrjones`
```
...will not list the service, because it is running at system level.
<a id="useful-links-launchd"></a>
#### Useful Links launchd [🔝](#contents)
- [launchd.info](http://www.launchd.info)
- [developer.apple.com **Daemons and Services Programming Guide**](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-BCIEDDBJ)
- [osxdaily **remove launchd service**](http://osxdaily.com/2011/03/08/remove-an-agent-from-launchd/)
- [launchd.plist **env vars**](http://www.dowdandassociates.com/blog/content/howto-set-an-environment-variable-in-mac-os-x-launchd-plist/)
- [Babo D's Corner **Launchctl 2.0 Syntax**](https://babodee.wordpress.com/2016/04/09/launchctl-2-0-syntax)
#### TODOs launchd
- [x] ~~see if environment variables can be used in `.sh` associated with launchd.~~
- [x] ~~see if environment variables can be used in `.plist` files associated with launchd.~~
<a id="working-with-devices-on-macos"></a>
### Working with devices on macOS [🔝](#contents)
To status devices, ie. devices connected via Bluetooth or USB, macOS provides **ioreg** and **system_profiler**
Either one of the tools can be used from the CLI to status devices internal or external to a running version of macOS.
To get a crude list of devices attached to a USB bus on macOS
```shell
ioreg -p IOUSB
```
> The **-p** flag will scan the ioregistry over a given plane, and in the above example the plane specified is **IOUSB**.
To get more verbose / detailed information about USB devices connected to macOS
```shell
ioreg -p IOUSB -w0 -l
```
**-w0** will not constrain the output to the width of the window ,and the **-l** will add to the verbosity of the **ioreg** command.
⚠️ The **-l** flag is useful for listing the **idProduct** and **idVendor**
An alternative to **ioreg** is **system_profiler**
To status USB devices connected to macOS using **system_profiler**
```shell
system_profiler SPUSBDataType
```
<a id="working-with-kernel-boot-arguments"></a>
### Working with Kernel, ie. Darwin boot arguments [🔝](#contents)
To manually kernel boot arguments for the Darwin kernel on macOS, edit the below file.
```conf
/Library/Preferences/SystemConfiguration/com.apple.Boot.plist
```
<a id="working-with-graphics-programming-on-macos"></a>
### Working with Graphics Programming on macOS [🔝](#contents)
<a id="working-with-opengl-on-macos"></a>
#### Working with OpenGL on macOS [🔝](#contents)
macOS does not ship with OpenGL header files for building programs against OpenGL, however Xcode can be installed to build against some of the OpenGL header files.
To the best of my knowledge Apple stopped pulling in upstream features of OpenGL as of v3.2.
<!-- insert image -->
![macos-opengl](https://raw.githubusercontent.com/wiki/ipatch/dotfiles/lib/macos-opengl-support.png)
That said, certain apps that use Vulkan, ie. the successor to OpenGL run on macOS.
<a id="working-with-postgres"></a>
### Working with Postgres [🔝](#contents)
To start the homebrew implementation of PostgreSQL
```shell
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
```
> The above command will load the homebrew implementation PostgreSQL as a service using launchd on macOS.
To verify if the service is running
```shell
launchctl list | grep -i "homebrew"
```
To stop the newly added launchd service
```shell
launchctl stop [com.mr-fancy-service]
```
or
```shell
launchctl unload [com.mr-fancy-service]
```
#### Troubleshooting Postgres on macOS
Make sure the Postgres data directories on macOS have a **700** permission
```shell
/usr/local/var/postgres
```
<a id="working-with-screen-savers-on-macos"></a>
### Working with Screen Savers on macOS [🔝](#contents)
The default location for system Screen Savers on macOS
```conf
/System/Library/Screen Savers/
```
The default `$USER` location for screen savers on macOS
```conf
~/Library/Screen Savers/
```
#### Useful Links [🔝](#contents)
- [**osxdaily.com** default screen saver locations](http://osxdaily.com/2018/06/03/default-screen-saver-locations-mac/)
- [**StackExchange** setting `asciiquarium` as a screen saver](https://unix.stackexchange.com/questions/395151/how-can-i-install-asciiquarium-as-a-screensaver)
#### TODO [🔝](#contents)
- [ ] Mess around with Screen Saver project template in Xcode
<a id="working-with-applescript"></a>
### Working with AppleScript [🔝](#contents)
<a id="useful-links-applescript"></a>
#### Useful Links AppleScript [🔝](#contents)
- [The language of automation](https://macosxautomation.com/applescript/firsttutorial/11.html)
- [GitHubGist - upgrading Postgres](https://gist.github.com/olivierlacan/e1bf5c34bc9f82e06bc0)
### Working with Messages [🔝](#contents)
To instert a newline or line break using Messages
<kbd>option</kbd> + <kbd>return</kbd>
<a id="linux"></a>
## Linux [🔝](#contents)
- [ ] **TODO** Add a graphic to symbolize GNU+Linux to quickly see when browsing document in a web browser!
<a id="working-with-dkms"></a>
### Working with dkms
To print a list of _added_ dkms modules in the various versions of linux kernels
```shell
sudo dkms status
```
> ❗️ there is a difference between a **addedd** and **installed** kernel module.
To remove a **dkms** kernel module for all kernels present on a system
```shell
dkms remove <module>/<module-version> --all
```
> The **--all** flag should remove all versions of the specified module for all kernels on the system.
<a id="linux-general-commands"></a>
### General Commands
To print the **UUID** for a hard disk or a partition of a hard disk
```shell
blkid
```
To find the `/dev` node asosciated with a removable storage device, ie. a USB flash drive.
```shell
dmesg
```
Run the above mentioned command after attaching a USB disk to see what the `/dev` node, ie. `/dev/sdd` is asosciated with the device.
> Partitions for a particular USB drive are listed as `/dev/sdd1`, `/dev/sdd2`, etc. etc.
To print the major & minor release version of a Debian system
```shell
lsb_release -a
```
To mount a partition with an ext2 filesytem
```shell
mount -t ext2 /dev/sda1 /opt
```
To change the hostname of the system
```shell
hostnamectl set-hostname mr-fancy-pants-hostname-here
```
To extract a directory of rar files
```shell
find . -name "*.rar" -exec unrar x -o+ {} \;
```
<a id="resizing-a-partition-for-a-qemu-virtual-disk"></a>
#### Resizing a partition for a QEMU virtual disk
If a virtual hard disk for a QEMU VM needs to be increased then **fdisk** can be used to increase the partition after **qemu-img** has been used to increase the size of the virtual disk.
To increase the size a virtual **qcow** disk
```shell
qemu-img resize /path/to/virtual-disk.qcow2 10G # resize disk to 10G
```
To add 10 Gigabytes to a virtual disk
```shell
qemu-img resize /path/to/virtual-disk.qcow2 +10G # append 10G to virtual disk
```
<a id="linux-working-with-users-and-groups"></a>
### Working with Users and Groups [🔝](#contents)
To change the login password for a user on a GNU+Linux system
```shell
sudo passwd $USER
sudo passwd mr-fancy
```
To change the UID for a user on a GNU+Linux system
```shell
usermod -u [NEW_UID] mr-fancy
```
> ❗️mr-fancy can not change his own UID and no processes can be associated with mr-fancy. If mr-fancy has associated processes run the below commands
```shell
pkill -u mr-fancy pid
pkill -9 -u mr-fancy
```
The same procedure is applicable for changing the GID of _mr-fancy_ as well
```shell
groupmod -g [NEW_GID] mr-fancy
```
❗️ Be certain to update old files and dirs that were associated with the **GID** [see](https://www.cyberciti.biz/faq/linux-change-user-group-uid-gid-for-all-owned-files/)
To print the **GID** for a particular group name ie. **staff**
```shell
getent group staff
```
To print the **GID** of a group name of macOS
```shell
dscl . -read /Group/staff | awk '($1 == "PrimaryGroupID:") { print $2 }'
```
#### Raspbian > Working with sudo
To set an empty / blank password for the user **pi** on Raspbian
1. Make certain the **pi** user has sudo permissions.
❗️ The **pi** may require setting the default editor to run `visudo` otherwise the default editor will be set to **nano**
To set the default editor for **visudo**
```shell
sudo update-alternatives --config editor
```
2. Add the below line to **/etc/sudoers**
```conf
pi ALL=(ALL) NOPASSWD:ALL
```
3. Delete the current password for the **pi** user
```shell
sudo passwd -d `whoami`
```
After the above settings have been made the **pi** user should be able to login without being prompted for a password.
<a id="working-with-tty"></a>
#### Working with tty / pts from a CLI
A quick way to list **tty**'s / **pts**'s on a GNU+Linux distro
```shell
w
```
- ❗️ On **macOS** listing all active terminal sessions is a little different, and the **w** command only shows the initial console session when running `w`. However, a crude count can be obtained by listing all **/dev/ttysXXX*** devices within the **dev** directory.
- [To print print the active pseudo terminal / tty for a shell
```shell
tty
```
- To kill a different tty from an existing tty session
```shell
pkill -9 -t pts/[NUMBER]
```
<strong>TODO</strong>
```shell
ps -ft pts/[NUMBER] pts/42 pts/24
kill [PID] [PID]
```
> ❗️ BSD and macOS are different beasts from GNU+Linux
To list the default options that will be applied when creating a new user on the system
```shell
useradd -D
```
To delete a user from the system, for more info [see](https://www.cyberciti.biz/faq/linux-remove-user-command/)
```shell
userdel mr_fancy_user
```
To create a new user with a specified shell, home directory, and user name
> [see](https://www.thegeekstuff.com/2009/06/useradd-adduser-newuser-how-to-create-linux-users/)
```shell
useradd -s /bin/bash -m -d /home/vanilla vanilla
```
To print a users home directory, ie. `/home/mr-fancy-42-user`
```shell
grep mr-fancy-42-user /etc/passwd | cut -d ":" -f6
```
<a id="setting-new-files-in-a-directory-to-belong-to-a-particular-group"></a>
#### Setting new files in a directory to belong to a particular group [🔝](#contents)
1. Set the directory to have a **umask** of 007
```shell
umask 007
```
> The above command will make all newly created files to
```shell
u=rwx,g=rwx,o=
```
To verify the above setting
```shell
umask -S
```
To remove the **setuid** ie. _sticky_ bits from a directory
```shell
chmod ug-s /path/to/dir
echo "or try the below"
chmod 0755 /path/to/dir
```
To print **all** users on a Linux box
```shell
cut -d: -f1 /etc/passwd
```
To print **all** groups on a Linux system
```shell
cut -d: -f1 /etc/group
```
To print user and groups values of a particular user
```shell
id [user_name]
```
To print the group memberships for a particular user
```shell
groups [mr_fancy_user_name]
```
To create a new group on a Linux system
```shell
groupadd [mr-fancy-42-group]
```
To add an existing Linux system user to an existing group
```shell
usermod -a -G [name_of_group] [name_of_user]
```
> If adding a $USER to a group on a remote system through ssh more than likely the $USER will have to logout and then log back in after adding the $USER to a group.
<strong>Ex</strong>
```shell
usermod -a -G prettyladies diana
```
<a id="working-with-disks-block-devices-and-filesystems-on-linux"></a>
### Working with disks block devices and filesystems on Linux [🔝](#contents)
To list all the partitions for block devices, ie. disks on a Linux system
```shell
lsblk
echo "for more a descriptive listing"
lsblk -f
```
To create, modify, delete a partition on Linux system, **gparted** is a popular command
> **gparted** only works with devices and volumes, ie disks and partitions.
To display the **free space** on a disk using **gparted**
```shell
gparted /dev/disk
(parted) print free
```
To display the partition labels for a particular device, ie. disk
```shell
e2label /dev/disk
```
To display a partition label for a particular volume / partition
```shell
e2label /dev/disk[Partiton#]
```
To set a label for a partition which can referenced ie in a **/etc/fstab** file for auto mounting a file system when present.
```shell
e2label /dev/disk[Parttion#] [mr-fancy-partition-label]
```
To remove a partition label
```shell
e2label /dev/disk[Parttion#] ""
```
To create **FAT-32** file system on a removable USB device on the **3rd** partition / volume of the device
```shell
mkdosfs -F 32 -I /dev/sda3
```
> /dev/sda is dependent on the disk path!
To remove a removable USB disk from a Linux system, make sure all partitions have been unmounted, then use **udisksctl**
- **keywords** power, off, turn, poweroff, turnoff, USB, powerdown, down
```shell
udiskctl power-off -b /dev/sd[A,B,C]
```
> **[A,B,C]** refers to the disk that one would like to unmount.
To safely remove a USB mass storage, 1) unmount the disks, 2) then power down the drive
```shell
sudo udisks --unmount /dev/sd[???]
echo "the below command will power down the drive
sudo udisks --detach /dev/[sd[???]
```
#### Working with autofs
To unmount all filesystems that have been mounted with **autofs**
```shell
umount -a -t autofs
```
<a id="working-with-udev"></a>
### Working with udev [🔝](#contents)
For an exhaustive guide to working with udev, [see](http://www.reactivated.net/writing_udev_rules.html)
To print the currently installed version of udev
```shell
udevadm version
```
To setup a custom network interface name using **udev** for a standard interface name, ie. **eth0** or **wlan0** create a **70-persistent-net.rules** within `/etc/udev/rules.d`
```conf
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="01:23:45:ab:cd:ef", NAME="eth-pi"
```
<a href="selinux"></a>
### SELinux [🔝](#contents)
> Stretch enabled support for [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) on Debian, but is disabled on a default install.
To check whether **SELinux** is enabled / disabled on Stretch
```shell
grep FSC /etc/default/rcS
```
If the output from the above command returns
```shell
FSCKFIX=no
```
then **SELinux** has not been enabled on the box.
Another way to check if **SELinux** is enabled / disabled on a Debian 9.x box.
```shell
sestatus
```
<a name="debian"></a>
### Debian [🔝](#contents)
<a href="setting-up-backports-on-debian-stretch"></a>
#### Setting up backports on Debian Stretch [🔝](#contents)
To setup Debian Stretch 9.x to work with a **backports-repo**
1. Edit `/etc/apt/sources.list` file or add a `.list` file, ie. a `debian-strech-backports.list` file within the `/etc/apt/sources.list.d/` directory and add the below entry.
```shell
deb http://ftp.debian.org/debian stretch-backports main
```
To install a package from a backports repo
```shell
apt-get update
apt-get -t stretch-backports install [mr-fancy-backport-package]
```
For more info on working with **backports** [see](https://backports.debian.org/Instructions/)
<a id="linux-debian-working-with-apt"></a>
#### Debian > Working with _apt_ & _apt-get_
To generate a list of all packages installed with `apt` / `apt-get`
```shell
dpkg --get-selection
```
> Debian 9.x and above provides **apt-mark**
To generate a list of all manually installed packages by a user, and **not** their dependencies
```shell
apt-mark showmanual > [mr-fancy-42-package.list.txt]
```
To reinstall all the **manually** installed packages provided by **apt** / **apt-get**
```shell
xargs < [mr-fancy-42-package.list.txt] apt-get install
```
To print a list of files associated with a package
```shell
dpkg -L [mr-fancy-42-package]
```
To show package records for a particular package
```shell
apt-cache show postgresql
```
To remove a specific version from the list
```shell
apt-get remove postgresql=9.6+181+deb9u1
```
To list all packages related to particular string, ie. [postgres]
```shell
dpkg --get-selections | grep postgres
```
To display the package version number of all packages currently installed on the system
```shell
dpkg-query -l
```
To find the package that provides a particular ".h" file
```shell
dpkg -S <name_of_h_file.h>
```
Example,
```shell
dpkg -S stdio.h
```
Output
> libc6-dev: /usr/include/stdio.h<br />
> libc6-dev: /usr/include/bits/stdio.h<br />
> perl: /usr/lib/perl/5.6.0/CORE/nostdio.h<br />
Adding a key signature to apt-get, [see](https://github.com/yarnpkg/yarn/issues/4505)
To remove artifacts from `apt-get` installed packages
```shell
rm -rf /var/lib/apt/lists/*
```
then rerun the below command.
```shell
apt-get update
```
To see what packages can be upgraded
```shell
apt-get upgrade --dry-run
```
To **search** for a particular package from the `apt-get` sources
```shell
apt-cache search [mr-fancy-apt-package]
```
To **show** or list the dependencies a package requires using `apt`
```shell
apt-cache depends [mr-fancy-package]
```
ie.
```shell
apt-cache depends xsel
```
or
```shell
apt-cache depends xclip
```
> Running `apt-get update` on Debian 9.x was giving an expired an key error.
See the following [issue](https://github.com/fish-shell/fish-shell/issues/4753) about getting the updated key in order to resolve the expired key issue for OpenSuse server, ie. it is related to fish shell.
To reinstall an _app_ on Debian using `apt-get`
```shell
apt-get install --reinstall postgresql
```
To download the source for a particular package that would installed using **apt-get** command
```shell
apt-get source [packagename]
```
To pin / hold back a package from being upgraded via **apt** or **apt-get**
```shell
sudo apt-mark hold [PACKAGE_NAME]
```
To unpin / unhold a package
```shell
sudo apt-mark unhold [PACKAGE_NAME]
```
To add a **path** for every user on the system edit `/etc/login.defs` add the respected **path** entries for normal users, and the root user.
<a id="troubleshooting-apt-on-debian"></a>
##### Troubleshooting apt on Debian
###### Debian > apt > troubleshooting partial install
**Error** message
> apt 2 not fully installed or removed.
To list the partially installed or removed packages
```shell
dpkg -C
```
Then remove or reinstall the offending apt packages
```shell
apt install [OFFENDING_PKG]
apt install --force-yes [OFFENDING_PKG]
apt remove [OFFENDING_PKG]
apt remove --force-yes [OFFENDING_PKG]
```
From my empirical evidence **apt** performs without errors if there is only a single version of python in the **PATH**, ie. do not have **pyenv** to use both a 2.7.x and a 3.{6,7}.x variant of python with the below command
```shell
pyenv global system 3.6.5 2.7.15
```
Instead **use**
```shell
pyenv global system 3.6.5
```
<a id="debian-date-time-timezone"></a>
#### Debian date, time, timezone [🔝](#contents)
The quickest way to setup the proper time + date, and correct timezone is to install **ntp** if a network connection is present.
```shell
apt-get install ntp
```
To configure the Debian system for a specific timezone, ie. US Centeral TZ
```shell
sudo dpkg-reconfigure tzdata
```
> Follow the curses based menus for setting up tz data.
#### Debian Working with KVM [🔝](#contents)
- [**wiki.debian.org** KVM](https://wiki.debian.org/KVM)
<a id="debian-stretch-9.x"></a>
#### Debian Stretch, ie. 9.x [🔝](#contents)
<a id="setting-up-selinux-on-debian"></a>
#### Setting up SELinux on Debian [🔝](#contents)
```shell
apt-get install selinux-basics selinux-policy-default auditd
```
- Download the [**_load_selinux_policy**](https://wiki.debian.org/SELinux/Setup?action=AttachFile&do=view&target=_load_selinux_policy) script.
- Move the script into `/usr/share/initramfs-tools/scripts/init-bottom`
- Run `update-initramfs -u`
- Run `selinux-activate` to configure GRUB and PAM to work with **SELinux**
1. Create `/.autorelabel`
- Reboot the system.
1. Run `check-selinux-installation` to see the errors / warnings about **SELinux**
- Finally add `enforcing=1` to `/etc/default/grub`
- Reboot
> Debian packaged kernels provide support for **SELinux** out the box.
<a id="selinux-useful-links"></a>
#### SELinux Useful Links [🔝](#contents)
- [**Debian wiki** SELinux](https://wiki.debian.org/SELinux/Setup)
- [**Debian wiki** SELinux Prereqs](https://wiki.debian.org/SELinux/Setup#kernel)
<a id="working-with-apt"></a>
#### Working with `apt` [🔝](#contents)
To remove / purge old packages `.deb` files on a Debian system
```shell
sudo aptitude clean
```
<a id="linux-apt-reseach-missing-packages"></a>
##### Research missing packages with apt [🔝](#contents)
To get a list of files a package can provide install **apt-file**, generate a DB for **apt-file** and then query **apt-file** with search strings. Also, **apt-file** can take a `list` argument to see what files a package provides, ie.
```shell
apt-file list libglib2.0-dev | grep '.m4$'
```
```shell
sudo apt-get update; \
sudo apt-get sudo apt-get install apt-file \
sudo apt-file update
apt-file search [string]
```
[**Credit**](https://unix.stackexchange.com/a/456459/33002)
<a id="working-with-source-code-using-apt-get"></a>
##### Working with source code using apt-get [🔝](#contents)
> Source code for Debian packages installed via `apt-get` is currently being maintained on [salsa.debian.org](https://salsa.debian.org)
An account will need me made on the _GitLab_ clone thingy, ie. server specifically designed for Debian packages, and then the apropriate package can be cloned to a local box.
To clone a package from **salsa.debian.org**
1. `sudo apt-get install git-buildpackage`
2. `gbp clone git@salsa.debian.org:[mr-fancy-guest]/[mr-fancy-42-package].git`
To build a debian package from source using a git clone
```shell
cd [mr-fancy-42-package]/
gbp buildpackage --git-pbuilder
```
<a id="pbuilder-howto"></a>
##### Pbuilder Howto [🔝](#contents)
<a id="apt-get-useful-links"></a>
##### Working with source using apt-get Useful Links [🔝](#contents)
- [**wiki.ubuntu.com** Pbuilder Howto](https://wiki.ubuntu.com/PbuilderHowto)
- [**debian.org** Packaging Tutorial](https://www.debian.org/doc/manuals/packaging-tutorial/packaging-tutorial.en.pdf)
<a id="troubleshooting-apt"></a>
#### Troubleshooting apt [🔝](#contents)
If `apt-get` is having difficulty finding scripts to run, ie. `/usr/sbin/update-info-dir` make certain that `/usr/sbin` is in the current `$USER`'s `$PATH`
<a id="upgrading-from-jessie-to-stretch"></a>
#### Upgrading from Jessie to Stretch [🔝](#contents)
> Make sure all Jessie updates have been applied to the system first. To make sure no updates need to be applied
```shell
apt-get update upgrade --dry-run
```
Then run the two below commands to make sure there are no issues pending
```shell
dpkg --audit
dpkg --get-selection | grep hold
```
> Services such as postgres will need to be halted when performing a system upgrade because tools / libs ie, lib-c require them to be halted during the upgrade process.
To stop the postgres service on Debian jessie
```shell
/etc/init.d/postgresql-[version] stop
```
If postgres has been setup to work with systemd then the postgres server can be halted with the below command.
```shell
systemctl stop postgres
```
Then edit `sources.list`
```shell
nvim /etc/apt/sources.list
```
Remove or comment out source entries related to jessie and add the below entries related for stretch
<!-- NOTE: make sure to add a newline before and after fenced code blocks -->
```shell
deb http://mirrors.digitalocean.com/debian stretch main
deb-src http://mirrors.digitalocean.com/debian stretch main
deb http://security.debian.org/ stretch/updates main
deb-src http://security.debian.org/ stretch/updates main
deb http://mirrors.digitalocean.com/debian stretch-updates main
deb-src http://mirrors.digitalocean.com/debian stretch-updates main
```
Then run the below commands again
```shell
apt-get update
apt-get upgrade
```
Then run the below command
```shell
apt-get dist-upgrade
```
If the upgrade process halts for whatever reason it can be resumed using the below command
```shell
apt-get -f dist-upgrade
```
After everything has been installed, and the system has been rebooted, the old kernels can be purged.
```shell
dpkg --list | grep linux-image
aptitude purge ~ilinux-image-\[0-9\]\(\!`uname -r`\)
```
To purge / remove unneeded packages from the system
```shell
apt-get remove --purge
```
<a id="working-with-cron"></a>
### Working with `cron` [🔝](#contents)
- [crontab.guru - generate cron entries](https://crontab.guru/)
To test the various cron tasks on a Debian system
```shell
run-parts /etc/cron.daily
run-parts /etc/cron.weekly
run-parts /etc/cron.monthly
```
To arbitrarily run a cron job with the _bare metal_ cron setup see
[this](https://unix.stackexchange.com/a/213302/33002)
To display the particular cron jobs for a user on a Debian box.
```shell
crontab -l
```
> The file printed from the above command is stored in the following in the following location on the system.
```shell
/var/spool/cron/cron/crontabs/
```
> When running a cron job / shell script make sure the script does not contain any commands being run with `sudo`. Long story short, a password will have to be stored in plain text somewhere on the system. 😬 When using env vars in a shell script run by cron make sure the env vars are set within the script itself.
See [this](https://askubuntu.com/questions/173924) for more details.
<a id="working-with-pamd"></a>
### Working with pam.d [🔝](#contents)
To restart the **pam.d** service
```shell
/usr/sbin/pam-auth-update
```
<a id="working-with-locales"></a>
### Working with locales [🔝](#contents)
**Update** February 17 2019
The below command resolved locale issues I was having after upgrading locales on Debian Stretch [see](https://github.com/Linuxbrew/brew/issues/568#issuecomment-367417842) for more info.
```shell
sudo sh -c 'echo en_US.UTF-8 UTF-8 >>/etc/locale.gen' && sudo /usr/sbin/locale-gen
```
To list the locales on a system
```shell
locale -a
```
To configure locales on a Debian based distro, ie. Raspbian
```shell
dpkg-reconfigure locales
```
> Follow the instructions in the curses based menu program. ⚠ `dpkg-reconfigure locales` must be run as **root** and not used via **sudo**
🚨 When generating locales using `locale-gen` run as root do not use `sudo` if you value your sanity 👩‍⚕️
To remove erronous locales from a system edit `/etc/locale.gen` and comment out the unnecessary locales.
The [following](https://askubuntu.com/a/144448/134740) link appears to have resolved the locale / perl warnings
To fix a broken locale system on a Debian box, [see](https://unix.stackexchange.com/questions/110757)
To remove unused / extra locales on a Debian box
```shell
sudo apt-get install localepurge
```
Unselect all the locales that aren't being used.
> When changing *locale* for a particular user, sometimes reloading the shell, ie. `exec bash` will not pick up on the *locale* change, so it's important to "logout" and "log" back in.
<a id="useful-commands-for-working-with-locales"></a>
#### Useful Commands for Working with locales [🔝](#contents)
```shell
apt-get install localepurge
```
```shell
bass . /etc/default/locale
```
```shell
dpkg-reconfigure localepurge
```
<a id="postgresql"></a>
### Postgresql [🔝](#contents)
#### General Notes about working with PostgreSQL [🔝](#contents)
To check the server version of PostgreSQL if it has been installed
```shell
postgres -V
```
To check the installed version the PostgreSQL client
```shell
psql -V
```
<strong>TL;DR</strong>
To restart PostgreSQL on Debian 8.x & 9.x
```shell
/usr/lib/postgresql/10/bin/pg_ctl -D /path/to/where/DBs/are/located -l /path/to/server/log/file.log start
```
> `pg_ctl` can be located in different locations depending on how PostgreSQL was installed.
For my particular Digtal Ocean droplet the below command works 👍
```shell
/usr/lib/postgresql/10/bin/pg_ctl -D /var/lib/postgresql/10_3_1 -l /usr/local/var/postgres/server.log start
```
> The above command should be run as the `postgres` user on the system, DO NOT USE `sudo` or `root` to start the daemon unless you like headaches 🤕 If the [postgresql.service](https://github.com/ipatch/dotfiles/blob/master/jobs/Linux/systemd/postgresql.service) is being used in conjuction with PostgreSQL then the postgres can be controlled via Systemd
```shell
systemctl start postgresql.service
```
To check and see if postgresql server is running on the system
```shell
ps -ef | grep postgre
```
To reload postgresql
```shell
/etc/init.d/postgresql reload
```
To create a user for Postgres
```shell
createdb [mr-fancy-42-user]
```
> The above command helps alleviate the common below error message
```shell
psql: FATAL: database [user] does not exist
```
<a id="postgres-backing-up-databases"></a>
#### Postgres Backing up databases [🔝](#contents)
To implement a backup solution for postgres, [see](https://wiki.postgresql.org/wiki/Automated_Backup_on_Linux)
To setup a `cron` job to run the backup scripts daily copy or symlink `pg_back*` in the `Linux` dir within the `jobs` dir.
To test a daily cron job on Debain Linux
```shell
run-parts -v /etc/cron.daily -v
```
To back a Postgresql database, [see](https://www.digitalocean.com/community/tutorials/how-to-backup-postgresql-databases-on-an-ubuntu-vps) for more details.
```shell
pg_dump [name_of_database] > name_of_backup_file.sql
```
#### Postgres Restoring a database [🔝](#contents)
> As of June 30 2018 I have a couple of shell scripts running to automate the process of taking daily snapshots of my Postgres databases. That said the scripts produce two back up files, ie. a **.gz** and a **.custom**
To restore a Postgres database from a snapshot using the `.custom` file, use the following,
```shell
pg_restore --dbname=mr-fancy-42-db --verbose --host=localhost --username=mr-fancy-username --password ~/path/to/mr-fancy-42-db.custom
```
> When restoring a DB that works with a rails web application, make sure to restore the DB, before running the migrations, and then run the migrations after restoring the database. 👌
If the `schema.rb` file is affected from importing data, and migrations are rerun, more than likely puma will need to be restarted after intitial deploy with new data in the database.
<a id="working-with-postgres-on-debian"></a>
#### Working with Postgres on Debian [🔝](#contents)
> `pg_ctlcluster` supersedes `pg_ctl` and in practice `pg_ctlcluster` should be used in favor of using `pg_ctl` when possible. That said, `pg_ctl` can be found at the below location
```shell
/usr/lib/postgresql/[MAJOR.MINOR]/bin/pg_ctl
```
The PostgreSQL configuration files, ie. `pg_hba.con` are located in the below location
```shell
/var/lib/postgresql/10_3_1/
```
The postgres binaries, ie. commands are located in the below location
```shell
/usr/lib/postgresql/10/bin
```
> `psql` is located in both `/usr/bin/psql` and `/usr/lib/postgresql/10/bin`
<a id="getting-postgres-to-work-with-systemd"></a>
##### Getting postgres to work with systemd
> `postgresql@.service` acts a template for setting up postgres to work with systemd.
The units file that interacts with Postgres server is,
```shell
/lib/systemd/system/postgresql.service
```
As of March 21, 2018, all database records / data are stored in the below location
```shell
/var/lib/postgresql/10_3_1
```
<a id="upgrading-postgres-from-10-3-to-10-4"></a>
#### Upgrading Postgres from 10.3.x to 10.4.x [🔝](#contents)
1. Installed Postgresql 10.4.x using **apt-get**
2. Dumped all existing data from 10.3.x
```shell
pg_dumpall > backup-may-30-2018
```
3. Stop the current database server, ie. Postgresql 10.3.x
```shell
pg_ctl stop
```
if using **systemd**
```shell
systemctl stop postgresql
```
4. Create a new **database cluster**
```shell
initdb -D /var/lib/postgresql/10_4_1
```
5. Start the new database server
```shell
postgres -D /var/lib/postgresql/10_4_1
```
> systemd
```shell
systemctl start postgresql
```
6. Restore the data from 10_3_1
```shell
psql -d postgres -f m backup-may-30-2018
```
> For more detailed instructions [see](https://www.postgresql.org/docs/10/static/upgrading.html)
<a id="working-with-psql"></a>
#### Working with `psql` [🔝](#contents)
To connect to a particular database using `psql`
```sql
postgres=# \connect database_name
```
To list all the databases
```sql
postgres=# \list
```
To list all tables for a particular database
```sql
postgres=# \dt
```
To change the owner of a particular database
```sql
postgres=# ALTER DATABASE [mr_fancy_database] OWNER TO [mr_fancy_owner_name];
```
#### PostgreSQL Useful Links [🔝](#contents)
- [the PostgreSQL Wiki](https://wiki.postgresql.org/wiki/Main_Page)
<a id="working-with-php"></a>
### Working with PHP [🔝](#contents)
To restart the PHP service / process
```shell
/etc/init.d/php5-fpm restart
```
To find the the local user on the system associated with the PHP service / process
> Create a php file with the following snippet
```php
<?php
phpinfo();
?>
```
Then look for a heading of **Environment** in the rendered output from the snippet.
<a id="working-with-nginx"></a>
### Nginx [🔝](#contents)
To restart nginx web server
```shell
service nginx restart
```
> The above command won't work on Debian 9.4 out of the box because it does not contain the `service` binary, instead use `systemd`, ie. `systemctl`
<a id="working-with-mysql"></a>
### Working with MySQL [🔝](#contents)
To install MySQL on a Debian based distro
```shell
apt-get install mysql-server
```
To complete the MySQL installation
```shell
mysql_secure_installation
```
To access the MySQL shell as the root user
```shell
mysql -u root -p
```
To list local MySQL databases on the system
```sql
show databases;
```
To show local permissions a particular user has on a system 📦
```sql
show grants for 'database_user'@'localhost';
```
Sometimes the below command will need to be run after making permission changes
```sql
flush privileges;
```
<a id="useful-links-mysql"></a>
#### Useful Links MySQL [🔝](#contents)
- [Official _MySQL_ reset root password](https://dev.mysql.com/doc/refman/5.7/en/resetting-permissions.html)
<a id="mediawiki"></a>
### MediaWiki [🔝](#contents)
> Make sure the proper user ie, the php user associated with the system has write permissions to the `images` directory
To see if Google Analytics is installed within mediawiki
> Special:Version
<a id="useful-links-mediawiki"></a>
#### Useful Links MediaWiki
- [MediaWiki > Extension > markdown parsers](https://www.mediawiki.org/wiki/Extension:Markdown)
- [GitHub > mediawiki > markdown parser > mw-markdown](https://github.com/bharley/mw-markdown/)
- [MediaWiki > Extension > Confirm Account](https://www.mediawiki.org/wiki/Extension:ConfirmAccount)
- [MediaWiki > To backup a mediawiki](https://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki)
- [setting per user `Xauthority`](https://stackoverflow.com/questions/22168626)
<a id="working-with-ssh"></a>
### Working with SSH [🔝](#contents)
To properly set permissions of SSH directories and files, see [🙈](https://superuser.com/questions/215504)
Some useful settings for setting up SSH permissions
1. `$HOME/.ssh` should be set to **700**
2. `$HOME/.ssh/[encryption_type].pub` should be set to **644**
3. `$HOME/.ssh/[encryption_type]` ie. `id_rsa` _the private key_ should be set to **600**
4. The users `$HOME` directory should not have a group write permission, and should be set to **755**
A useful command for **debugging** an SSH session, ie. debugging X11 Forwarding
```shell
ssh -v -X -l [mr_fancy_user_name] -p [mr_fancy_port] [hostname]
```
To suppress the **last login from X.X.X.X IP address**
1. Edit /path/to/sshd_config
Add the below line to the file
```conf
PrintLastLog no
```
To suppress the **connection from IP closed**
1. Edit `$HOME/.ssh/config`
Add the below setting
```conf
LogLevel QUIET
```
<a id="working-with-systemd"></a>
### Working with systemd [🔝](#contents)
To restart a Systemd service
```shell
sudo systemctl restart [NAME_OF_SERVICE]
```
<strong>Ex</strong>
```shell
sudo systemctl restart sshd
```
<a id="systemd-history"></a>
#### systemd History [🔝](#contents)
Systemd was introduced by RedHat to replace / compliment SYSV for Linux distributions. Traditionally SYSV used syslogd or rsyslogd to log errors and output to log files for services and daemons running on the system. However systemd provides own logging facility which interacts for special journal files.
#### Systemd Working with journaling [🔝](#contents)
To control the journaling settings for **systemd** edit the below
```conf
/etc/systemd/journald.conf
```
> To get journaling to work properly on Debian 9.x I had to explicity set compression for the journal files to `off`
To allow a standard user to access and manipulate log files controlled by the journaling capabilities provided by systemd, perform the below
1. Add the standard user, ie. `whoami` to the **systemd-journal** group.
> See notes above, about working with users and groups, if needed.
2. Make sure the path to the **journal** directory and all sub folders and files are writeable by the **systemd-journal** group, ie. 775 for `/var/log/journal`
To **rotate** logs generated by systemd, one can use the **--vacuum-time=2weeks** flag / option to the `journalctl` command to trim / shrink the size of log files.
On Debian 9.x **systemd** stores system services in the below location
```conf
/lib/systemd/system/[mr-fancy-system.service]
```
**systemd** also stores `$USER` services in the below location
```conf
/usr/lib/systemd/user/[mr-fancy-user.service]
```
To start a systemd service for a particular `$USER`
```shell
systemctl --user start [service-name]
```
> The full path and the `.service` extension can be omitted if the **unit** file, (ie. that is what systemd calls the `.service` files.) is either of the above mentioned paths.
To add a additionaly systemd unit file the preferred location to add a unit file is within the `/etc/systemd/system` directory on Debian.
The unit files located in the `/etc/systemd/system` will take precedence over the ones that are located in `/lib/systemd/system`. Also, if there is a already a Debian provided systemd unit file in `/lib/systemd/system` the user provided will be chosen if located in the `/etc/systemd/system` directory. 👍
To install libpam-systemd
```shell
apt-get install libpam-systemd
```
> See, [🙈](https://unix.stackexchange.com/a/120086/33002) for more details
To list all enabled services from systemctl
```shell
systemctl list-unit-files | grep enabled
```
To analyze system boot time, ie. measure startup time of GNU+Linux using **systemd** performance
```shell
systemd-analyze
```
> When modifying a systemd `.service` file, the below command will need to be executed in order for systemd to pick up on the changes.
```shell
systemctl daemon-reload
```
<a id="troubleshooting-systemd"></a>
### Troubleshooting systemd
To remove / delete old systemd log files
```shell
sudo journalctl --flush --rotate
sudo journalctl --vacuum-time=2d
```
> The above command will remove all non active logs, and delete all active logs that 2 days or older.
<a id="working-with-man-pages">
### Working with man pages [🔝](#contents)
**man** pages are divided into various groups, ie. man pages about using a specific command, ie. `uname` will be located within **Section 1** where as getting a understanding of how the programming works for the `uname` command will be located within **Section 2**
#### `man` page directory layout [🔝](#contents)
| Directory | Section | Name |
| --------- | ------- | ---- |
| man1 | (1) | User Commands |
| man2 | (2) | System Calls |
| man3 | (3) | Subroutines |
| man4 | (4) | Devices |
| man5 | (5) | File Formats |
| man6 | (6) | Games |
| man7 | (7) | Miscellaneous |
| man8 | (8) | Sys. Administration |
| manl | (l) | Local |
| mann | (n) | New |
| mano | (o) | Old |
When working with man pages on macOS user added CLI commands can store their man page in `/usr/local/share/man/man1`. The `man1` directory is reserved for user added CLI commands, but **make certain** the man page has a `.1` or a `.1.gz` unless you don't want to read 📖 the man page ಠ_ಠ
<a id="useful-links-man-pages"></a>
#### Useful Links man pages [🔝](#contents)
- [cyberciti.biz - HowTo: Linux / UNIX Create a Manpage](https://www.cyberciti.biz/faq/linux-unix-creating-a-manpage/)
<a id="working-with-ld"></a>
### Working with `ld` [🔝](#contents)
To print the ld search path, see [🙈](https://stackoverflow.com/questions/9922949/)
<a id="all-useful-links"></a>
## All Useful Links [🔝](#contents)
......
......