diff --git a/README.md b/README.md
index 42d739f..f209032 100755
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
---*This project is still under heavy development!*---
+\Please do not delete this file, as it is used to display help information.
+
# L A C K A D A I S I C A L
A collection of easy-to-understand, easy-to-use scripts, functions and aliases. Designed to be beginner-friendly but also useful!
@@ -34,8 +36,6 @@ lackadaisical` if you so desire.
To read this notice again, call the function 'daisy_help'.
===============================================================================
These are the included binaries and utilities:
- - calm:
- Reduce a process 'niceness' to 0.
- cdz:
This utility extracts an archive to /tmp and changes
directory to it in a new shell instance. Upon exit,
@@ -45,6 +45,25 @@ These are the included binaries and utilities:
NO_ARCHIVEMOUNT=1. The standard script supports zip,
tarballs, and rar archives. We recommend relying on
archivemount` if you have it installed.
+ - SquashFS tools (mount/umount/make/destroy-squash-image):
+ These convenient set of tools allow you to easily create
+ XZ-compressed SquashFS images from existing folders to save
+ disk space. The resulting folder is still writable since it is
+ mounted using an 'overlay' system. You can use 'make-squash-image'
+ to compresses an existing folder. These folders are automatically
+ mounted when you use 'cd' to navigate to them (via an alias).
+ When using 'make-squash-image' on an already mounted folder, it will
+ instead update the existing image. As of writing, we do not have a
+ SystemD service to auto-mount, however, you cam easily add auto-mount
+ as a cron job. Here is a list of tools, they all take the same
+ folder argument:
+ > make-squash-image: Converts the folder into a hidden image
+ on the same disk as the folder.
+ > mount-squash-image: Sets up a mount for the XZ image alongside
+ directories for changes
+ > umount-squash-image: Self-explanatory.
+ > destroy-squash-image: Extracts the image and essentially reverts
+ everything. File changes are kept, however.
- editx:
Uses your standard CLI editor to create/modify a
file and make it executable.
@@ -53,16 +72,32 @@ These are the included binaries and utilities:
not exist yet. When the file appears on disk, the
tool quits and simply returns the filename. This
can be used in personal workflows to stall a longer
- command that relies on the existence of said file.
- - newday:
- A basic but powerful journaling system. Recommended
- to be set up via crontab. Can be used for everything
- from diaries to general file storage to even BTRFS
- snapshots.
+ command that relies on the existence of said file.=
+ - agenda:
+ Sets up a folder that is backed by a date-based tree
+ directory structure. Requires an argument for the name
+ of the folder to generate. Generates a symlink in this
+ name to a date sub-folder in a local '.daisy' folder.
+ Format is
-> .daisy////.
+ Recommended to run via crontab - automatically cleans
+ up empty folders.
+ A symbolic link to the base of the folder's tree, ".tree",
+ is created in the root of the specified directly.
+ Can be used for everything you'd like to sort by date.
+ For example; a diary, browser downloads, backups, code.
- own:
A simple utility. It's effectively an alias for
"sudo chown -R user:user" on the target dir/file.
Root permissions required!
+ - sshp:
+ This is a wrapper for `ssh`, the meaning of the 'p' is "Plus".
+ Integrates SSHFS support. If both client and host have SSHFS,
+ this wrapper can be used to connect their file systems.
+ For example, if you need to move files from one machine to
+ another, you could do something like this:
+ "sshp -m /:/mnt/pc -m /home/claire:/home/claire claire@pyon.net"
+ If privilege escalation is necessary for FS access, you will
+ be asked for a password.
- shrc:
This tool allows you to edit the RC file for your
shell in your preferred editor. After saving, the
@@ -74,11 +109,11 @@ These are the included binaries and utilities:
This is a tool similar to which and others, the key
difference is that it returns partial matches. It can
be used to search for binaries.
- - binbox:
+ - scripbox:
This tool can be used to pack bash scripts into one
big megascript, much like how `busybox` works.
You can also make symlinks to it to invoke a specific
- script (as of writing, 11/25, symlinks do not work well).
+ script.
- bak/unbak:
These small utilities make backups of files by making
a copy with a .bak suffix. Unbak reverses the process
@@ -100,12 +135,27 @@ These are the included binaries and utilities:
Like chsh but for your editor (EDITOR env). A list
from which you can choose an installed editor
(CLI or GUI) is shown. This list is by no means complete.
+ The editor for LACKADAISICAL and the global editor are
+ separate. If the EDITOR variable is already defined,
+ only LD_EDITOR will be changed. LD_EDITOR is the editor
+ used by LACKADAISICAL utilities.
+ To override the global EDITOR variable, pass "-g".
+ To restore the normal behavior of checking for an earlier
+ definition of EDITOR after passing "-g", run `ched` without
+ arguments.
- cdf:
Use fzf to find a file and then cd to its location.
- cdp:
Similar to `cdf` but uses tree+peco for the query.
+ - clip:
+ An extremely simple utility that functions as a clipboard of sorts.
+ To set the variable, run "clip " or provide data via stdin.
+ To get the variable, simply run clip without any arguments.
+ The variable is stored locally in the shell as "LD_CLIP".
- ldrc:
Edits daisy.source and re-sources it, similarly to shrc.
+ Append "-e" to edit "extra.src", to add custom functions in the
+ lackadaisical namespace.
- daisy_reload:
Re-sources daisy.source. Essentially `ldrc` without
editing.
@@ -120,7 +170,10 @@ These are the included binaries and utilities:
decoded by passing the output(s) to `daisy_dec`.
The output of `daisy_enc` can be concatenated with the
output of another encoded file to create a multi-file
- base64 archive similar to `daisy_enc_multi`
+ base64 archive similar to `daisy_enc_multi`.
+ Does not support symlinks yet, and will instead treat it
+ as a full input file (reads the data of the linked file).
+ When using stdin, please provide a filename as argument.
- daisy_enc_multi:
A version of `daisy_enc` that encodes multiple
files and outputs `daisy_base64_data` blocks to a file
@@ -155,5 +208,18 @@ These are the included binaries and utilities:
`daisy_reload`
- daisy_list:
List all available commands without description.
+ - daisy_clear:
+ Removes all configuration, including aliases.
+ A backup is made and can be restored using "daisy_restore".
+ Triggers a reload.
+ - daisy_backup:
+ Backs up all config files. These can be restored using
+ "daisy_restore".
+ - daisy_restore:
+ Undoes "daisy_clear" by restoring config files.
+ Triggers a reload.
+ - ld_*:
+ All functions prefixed by "daisy_" are also available with
+ the prefix "ld_" via aliases provided in daisy.source.
--- END OF DAISY HELP ---
```
diff --git a/newday b/agenda
similarity index 54%
rename from newday
rename to agenda
index 6266505..837cd0f 100755
--- a/newday
+++ b/agenda
@@ -1,25 +1,31 @@
-#!/bin/sh
+#!/usr/bin/env bash
# This script is intended to be run via cron.
# It creates a folder structure in home for the current date in the following format:
-# $HOME/ByDate///
+# $HOME////
-# It also sets up a symlink in home: $HOME/Today
+# It also sets up a symlink for the tagged folder.
# This symlink will always point to the folder for the current date.
# Finally, it removes any folders without data, to prevent clutter.
-# - Why did you make this?
-# I remember things better when they have a date attached to them.
-# You can use this for a primitive form of note-taking, but aside from notes -
-# you can store any data this way.
-
LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
-dir_name=ByDate
-root_dir=$HOME/$dir_name
-today_sym=$HOME/Today
+if [[ $1 == '' ]]; then
+ echo "Usage: $LD_BIN "
+ echo "Creates a folder within '.daisy' in the current directory containing"
+ echo "a tree of dates associated with the folder name given by argument."
+ echo "A symlink is (re-)created at the same time with the same folder name."
+ echo "For example, if given the folder 'notes', this utility will:"
+ echo "- Create a folder '/.daisy/notes///'."
+ echo "- Create a symlink named 'notes' that points to it."
+ echo "It is recommended to run this via cron."
+ exit 1
+fi
+
+root_dir=$(dirname $1)/.daisy/$(basename $1)
+today_sym=$1
# Present day
today=$(date -I)
@@ -29,7 +35,7 @@ day=$(echo $today | awk -F"-" '{print $3}')
set -e
-function errorFn()
+function errorFn
{
error=$?
if [[ $error -gt 0 ]];
@@ -49,6 +55,6 @@ test -L "$today_sym" && rm -rf "$today_sym"
# Now we can set up today's directory
mkdir -p "$root_dir/$year/$month/$day"
-cd $root_dir
-ln -s "./$dir_name/$year/$month/$day" "$today_sym"
+ln -s "$root_dir/$year/$month/$day" "$today_sym"
+ln -s "$root_dir" "$today_sym/.tree"
exitcode=@?
diff --git a/calm b/calm
deleted file mode 100755
index 6e45689..0000000
--- a/calm
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-# Calm a process down
-# NEEDS_WORK: cleanup
-# calm == only one process
-# calm == all processes that match query
-# calm * == if used in proc or a folder with just PID files, if not you will get an error
-# calm .... OK
-# set's NICE value to 0
-# need sudo
-
-LD_INTERNAL=1
-. $(dirname $(realpath $0))/daisy.source
-
-pids=$@
-
-errorFn()
-{
- echo calm: Invalid operation or no such PID/process \(\"$(echo "$pids" | tr '\n' ' ' | cut -c -20)...\"\)
- exit
-}
-
-for pid in $pids
-do
- # Process to PID in elegant way
- newpids=$(pidof "$pid")
- if [ "$newpids" ]
- then
- binary=$pid
- pid=$newpids
- else
- newbins=$pid
- binary=$(ps -p "$pid" -o comm= 2>/dev/null )
- if [ $? != 0 ]
- then
- errorFn
- fi
- fi
-
- echo Calming down $pid \("$binary"\)...
- sudo renice -n 0 -p $pid;
-done
diff --git a/cdz b/cdz
index d39446b..a380222 100755
--- a/cdz
+++ b/cdz
@@ -1,8 +1,8 @@
-#!/bin/sh
+#!/usr/bin/env bash
if [[ $LD_INTERNAL -ne 1 ]];
then
- export LD_INTERNAL=1
+ LD_INTERNAL=1
. $(dirname $(realpath $0))/daisy.source
fi
@@ -28,6 +28,7 @@ hasmounter=$?
file "$target" 1>/dev/null
exitcode=$?
report=$(file "$target")
+name=$(echo $@ | sed 's/:.*//' | sed 's|.*/||')
# Check for archive type, supported types are zip/tar/rar
comm1=(:)
@@ -88,7 +89,7 @@ elif (( $israr == 0 )); then
comm3=(exit 1)
fi
elif (( $hasmounter == 0 )); then
- comm2=(archivemount "$target")
+ comm2=(archivemount -o allow_root -o use_ino "$target")
comm4=(cd ..)
comm5=(umount)
fi
@@ -101,18 +102,17 @@ dir=$(mktemp -d /tmp/extracted.XXXXXXXX)
"${comm2[@]}" $dir
"${comm3[@]}"
-currentpath=$(realpath .)
-cd $dir
+currentpath=$(pwd)
+sym="$currentpath/$name.tmp"
+ln -f -s "$dir" "$sym"
+cd "$sym"
-# With archivemount, making a symlink will alter the archive
-if (( $hasmounter == 1 )); then
- ln -s $currentpath ./link-back
- echo "A symlink to your original path has been created under the name \`link-back\`."
- echo "You can use this to copy out files, but you can also just access your filesystem regularly."
-fi
+echo "A symlink has been made under the name \"$sym\"."
+echo "This symlink points to the data directory \"$dir\"."
echo "Type 'exit' to exit the extracted archive's folder and auto-delete it."
eval $SHELL
"${comm4[@]}"
"${comm5[@]}" $dir
rm -rf $dir
+rm "$sym"
diff --git a/daisy.source b/daisy.source
index ade487f..c39ecba 100755
--- a/daisy.source
+++ b/daisy.source
@@ -1,4 +1,5 @@
-#!/bin/echo "This file can only be sourced, not run stand-alone." -- #!/bin/bash
+#!/usr/bin/bash
+#!/usr/bin/env -S echo "This file can only be sourced, not run stand-alone."
# LACKADAISICAL SOURCE-ABLE FILE
# Source this in your RC file or manually to receive some of the simpler
@@ -11,11 +12,21 @@
# only included if sourced from one of the included scripts, though you are
# free to bypass this by setting env variable LD_INTERNAL to 1.
-if [[ $LD_INTERNAL -eq 1 ]];
+# Pass _LD_DEBUG=1 during sourcing to see debug information on a variety of things.
+
+if [[ $LD_INTERNAL == 1 ]];
then
export LD_BIN=$(basename $0)
fi
+function ld_dbg
+{
+ if [[ $_LD_DEBUG == 1 ]];
+ then
+ $@
+ fi
+}
+
# Variables for use in other utilities
# Find the right argument for our folder
arg=$0
@@ -25,17 +36,26 @@ then
fi
# Check for dependencies
-function daisy_dependency_check
+function _daisy_dependency_check
{
- command -v $1 1>/dev/null 2>/dev/null;
+ BIN=$(command -v $1 2>/dev/null)
res=$?
+
echo $(($res ^ 1))
}
-LD_HAS_fzf=$(daisy_dependency_check fzf)
-LD_HAS_md5sum=$(daisy_dependency_check md5sum)
-LD_HAS_peco=$(daisy_dependency_check peco)
-LD_HAS_tree=$(daisy_dependency_check tree)
+LD_HAS_fzf=$(_daisy_dependency_check fzf)
+LD_HAS_md5sum=$(_daisy_dependency_check md5sum)
+LD_HAS_peco=$(_daisy_dependency_check peco)
+LD_HAS_tree=$(_daisy_dependency_check tree)
+LD_HAS_dialog=$(_daisy_dependency_check dialog)
+
+ld_dbg echo "Presence of utils:"
+ld_dbg echo fzf $LD_HAS_fzf
+ld_dbg echo md5sum $LD_HAS_md5sum
+ld_dbg echo peco $LD_HAS_peco
+ld_dbg echo tree $LD_HAS_tree
+ld_dbg echo dialog $LD_HAS_dialog
export LD_FOLDER=$(dirname $(realpath $arg))
export LD_SOURCE_FILE=$(realpath $arg)
@@ -57,11 +77,16 @@ fi
# [LEA.TODO] Turn these into arrays
LD_ALIASFILE="$LD_CONFIG_FOLDER/aliases.src"
LD_EDITORFILE="$LD_CONFIG_FOLDER/editor.src"
+LD_ESOURCEFILE="$LD_CONFIG_FOLDER/extra.src"
touch $LD_ALIASFILE
touch $LD_EDITORFILE
+ld_dbg echo "Sourced config contents:"
+ld_dbg cat $LD_ALIASFILE
+ld_dbg cat $LD_EDITORFILE
+
# Source everything in the config folder
-function _daisy_source_configs
+function _daisy_source_configs
{
for f in `find "$LD_CONFIG_FOLDER" -name "*.src" -type f`;
do
@@ -88,123 +113,8 @@ fi
# FUNCTIONS and ALIASES #######################################################
###############################################################################
-# bak and unbak
-function bak
-{
- # Input:
- target=$1
-
- # Check if file exists
- if ! test -f "$target";
- then
- echo "Path not found: \"$target\""
- return 2
- fi
-
- # Handle both cases
- if [[ $unbak_mode -eq 1 ]];
- then
- cp -R "$target.bak" "$target"
- rm -rf "$target.bak"
- echo "Restored backup: $target <-- $target.bak"
- else
- cp -R "$target" "$target.bak"
- echo "Backup made: $target --> $target.bak"
- fi
-}
-
-alias unbak="unbak_mode=1 bak"
-alias lsa="ls -a -l -h"
-alias lsn="ls -a -l -tu -r -h"
-alias lss="ls -a -l -S -r -h"
-
-# Simple version of `cdf`
-function cdf
-{
- if [[ $LD_HAS_fzf != 1 ]];
- then
- echo "This alias requires the utility 'fzf'. Please install it."
- return 1
- fi
- cd $(dirname $(fzf))
-}
-
-function cdp
-{
- if [[ $LD_HAS_peco != 1 || $LD_HAS_tree != 1 ]];
- then
- echo "This alias requires the utilities 'peco' and 'tree'. Please install them."
- echo "Consider using 'cdf' instead."
- return 1
- fi
- cd $(dirname $(tree -fia --noreport . | peco))
-}
-
-function editpeco
-{
- if [[ $LD_HAS_peco != 1 || $LD_HAS_tree != 1 ]];
- then
- echo "This alias requires the utilities 'peco' and 'tree'. Please install them."
- echo "Consider using 'cdf' instead."
- return 1
- fi
- tree --noreport -fia . | peco --prompt "Press CTRL+C to quit - query:" --exec "xargs -o -I{} $EDITOR {}"
-}
-
-# for convenience purposes
-function editbin
-{
- editx $(which $1)
-}
-
-# sets a new editor based on commony available ones, and some visual ones
-function ched
-{
- editors=("nano" "vim" "nvim" "vi" "emacs" "gedit" "kate" "mousepad" "micro" \
- "code" "subl" "joe" "kwrite" "gnome-text-editor")
-
- # Find which editors are installed
- available_editors=()
- for editor in "${editors[@]}";
- do
- editor_real=$(command -v "$editor")
- if command -v "$editor_real" >/dev/null 2>&1;
- then
- if [[ $(realpath "$EDITOR") == "$editor_real" ]];
- then
- available_editors+=("$editor_real" "$editor (current choice)")
- else
- available_editors+=("$editor_real" "$editor")
- fi
- fi
- done
-
- if [[ ! -z $@ ]];
- then
- text="$@"
- dialog --msgbox "$text" 0 0
- fi
-
- # Present all choices
- choice=$(dialog --output-fd 1 --clear --title "Select Text Editor" \
- --menu "Choose one of the installed text editors:" 15 50 6 \
- "${available_editors[@]}")
- dialog_ret=$?
-
- if [ $dialog_ret -ne 0 ];
- then
- echo "No editor selected."
- return
- fi
-
- echo export EDITOR=$choice > "$LD_EDITORFILE"
- echo export LD_EDITOR=$choice >> "$LD_EDITORFILE"
- echo export LD_OLD_EDITOR=$EDITOR >>"$LD_EDITORFILE"
-
- _daisy_source_configs
-}
-
-function wait_for_editor
+# Undocumented but internally used
+function daisy_wait_for_editor
{
pname="$1"
fname="$2"
@@ -223,32 +133,246 @@ function wait_for_editor
done
}
+function mountcd
+{
+ cdpath="$@"
+ if [[ $cdpath == '' ]];
+ then
+ \cd
+ fi
+ if [[ -f "$cdpath/.needs_mount" ]];
+ then
+ mount-squash-image "$cdpath"
+ fi
+ \cd "$cdpath"
+}
+
+alias cd=mountcd
+
+# Undocumented but internally used
+function daisy_editor
+{
+ editor=${LD_EDITOR:-$EDITOR};
+ ld_dbg echo Opening $editor to edit file: $1
+ $editor "$1"
+ daisy_wait_for_editor $editor "$1"
+}
+
+# bak and unbak
+function bak
+{
+ # Input:
+ target=$1
+
+ # Check if file exists
+ if ! test -f "$target";
+ then
+ echo "Path not found: \"$target\""
+ return 2
+ fi
+
+ # Handle both cases
+ if [[ $unbak_mode == 1 ]];
+ then
+ cp -R "$target.bak" "$target"
+ rm -rf "$target.bak"
+ echo "Restored backup: $target <-- $target.bak"
+ else
+ cp -R "$target" "$target.bak"
+ echo "Backup made: $target --> $target.bak"
+ fi
+}
+
+function unbak
+{
+ unbak_mode=1 bak $@
+}
+
+function lsa
+{
+ ls -a -l -h $@
+}
+
+function lsn
+{
+ ls -a -l -tu -r -h $@
+}
+
+function lss
+{
+ ls -a -l -S -r -h $@
+}
+
+# Simple version of `cdf`
+function cdf
+{
+ if [[ $LD_HAS_fzf != 1 ]];
+ then
+ echo "This function requires the utility 'fzf'. Please install it."
+ return 1
+ fi
+ cd "$(dirname "$(fzf)")"
+}
+
+function cdp
+{
+ if [[ $LD_HAS_peco != 1 || $LD_HAS_tree != 1 ]];
+ then
+ echo "This function requires the utilities 'peco' and 'tree'. Please install them."
+ echo "Consider using 'cdf' instead."
+ return 1
+ fi
+ cd $(dirname $(tree -fia --noreport . | peco))
+}
+
+function editpeco
+{
+ if [[ $LD_HAS_peco != 1 || $LD_HAS_tree != 1 ]];
+ then
+ echo "This function requires the utilities 'peco' and 'tree'. Please install them."
+ echo "Consider using 'cdf' instead."
+ return 1
+ fi
+ tree --noreport -fia . | peco --prompt "Press CTRL+C to quit - query:" --exec "xargs -o -I{} $EDITOR {}"
+}
+
+# for convenience purposes
+function editbin
+{
+ editx $(which $1)
+}
+
+# sets a new editor based on commony available ones, and some visual ones
+function ched
+{
+ override=0
+ if [[ $1 == "-g" ]];
+ then
+ override=1
+ fi
+
+ if [[ $LD_HAS_dialog != 1 ]];
+ then
+ echo "This function requires the utility 'dialog'. Please install it."
+ return 1
+ fi
+
+ editors=("nano" "vim" "nvim" "vi" "emacs" "gedit" "kate" "mousepad" "micro" \
+ "code" "subl" "joe" "kwrite" "gnome-text-editor")
+
+ # Find which editors are installed
+ available_editors=()
+ for editor in "${editors[@]}";
+ do
+ editor_real=$(command -v "$editor")
+ if command -v "$editor_rmeal" >/dev/null 2>&1;
+ then
+ if [[ $(realpath "$EDITOR") == "$editor_real" ]];
+ then
+ available_editors+=("$editor_real" "$editor (current)")
+ elif [[ $LD_EDITOR == "$editor_real" ]];
+ then
+ available_editors+=("$editor_real" "$editor (LD choice)")
+ else
+ available_editors+=("$editor_real" "$editor")
+ fi
+ fi
+ done
+
+ if [[ $override == 0 ]] && [[ ! -z $@ ]];
+ then
+ text="$@"
+ dialog --msgbox "$text" 0 0
+ elif [[ $override == 1 ]];
+ then
+ text="You have passed '-g'. Your choice of dialog will override any other choice or setting of 'EDITOR'."
+ dialog --msgbox "$text" 0 0
+ fi
+
+ # Present all choices
+ choice=$(dialog --output-fd 1 --clear --title "Select Text Editor" \
+ --menu "Choose one of the installed text editors:" 15 100 6 \
+ "${available_editors[@]}")
+ dialog_ret=$?
+
+ if [ $dialog_ret -ne 0 ];
+ then
+ dialog --msgbox "No editor selected. Variables will not be updated." 0 0
+ return 0
+ fi
+
+ [[ $override == 0 ]] && echo export EDITOR="${EDITOR:-$choice}" > "$LD_EDITORFILE"
+ [[ $override == 1 ]] && echo export EDITOR="$choice" > "$LD_EDITORFILE"
+ echo export LD_EDITOR="$choice" >> "$LD_EDITORFILE"
+ echo export LD_OLD_EDITOR="$EDITOR" >> "$LD_EDITORFILE"
+
+ source "$LD_EDITORFILE"
+}
+
function daisy_reload
{
- FROM_RC=0 source "$LD_SOURCE_FILE"
+ LD_INTERNAL=0 source "$LD_SOURCE_FILE"
}
function ldrc
{
- $EDITOR "$LD_SOURCE_FILE"
- FROM_RC=0 source "$LD_SOURCE_FILE"
+ if [[ $1 == "-e" ]];
+ then
+ daisy_editor "$LD_ESOURCEFILE"
+ else
+ daisy_editor "$LD_SOURCE_FILE"
+ fi
+
+ LD_INTERNAL=0 source "$LD_SOURCE_FILE"
}
+enc_is_folder=0
function daisy_enc
{
- if [ -d $1 ];
+ if [ -t 0 ] && [ -z "$1" ];
+ then
+ echo "# $0: No arguments or stdin specified!"
+ return 1;
+ fi
+
+ if [ ! -t 0 ] && [ -z "$1" ];
+ then
+ echo "# $0: Please provide a filename as argument when using stdin"
+ return 1;
+ fi
+
+ if [ -n "$1" ] && [ -d "$1" ];
then
echo -e "daisy_create_folder=$1"
else
- file_info=$(file $1)
- file_dir=$(dirname $1)
- file_name=$(basename $1)
+ file_dir=""
+ file_name=""
+ perms=755
+
+ target=$1
+
+ # [TODO, FIX: An unknown bug is causing daisy_enc_folder to misbehave if stdin is accessed, so we disable it here.]
+ if [[ ! -t 0 ]] && [[ $enc_is_folder == 0 ]];
+ then
+ file_dir="."
+ file_name="$1"
+ shift
+ elif [ -f "$1" ];
+ then
+ file_dir=$(dirname "$1")
+ file_name=$(basename "$1")
+ perms=$(stat -c %a "$1")
+ else
+ echo "# $0: An error occured during encoding."
+ return 1
+ fi
base64_inner=$(cat ${1:-/dev/stdin} | base64 | tr -d '\n')
# Print out our block
echo -e "daisy_folder_$file_name=$file_dir"
echo -e "daisy_data_base64_$file_name=\"$base64_inner\""
+ echo -e "daisy_perms_$file_name=$perms"
fi
}
@@ -272,13 +396,21 @@ function daisy_enc_folder
cd "$dir"
tree -fia --noreport . | sed 1d | while read -r item;
do
+ enc_is_folder=1
daisy_enc "$item"
+ enc_is_folder=0
done
}
function daisy_dec
{
+ if [ -t 0 ] && [ -z "$1" ];
+ then
+ echo "$0: No arguments or stdin specified!"
+ return 1;
+ fi
+
data=$(cat ${1:-/dev/stdin} | grep -v "#" )
echo -e "$data" | cut -d "=" -f 2- | cut -b 2- | head -c -2 | base64 -d
}
@@ -287,30 +419,48 @@ function daisy_dec
# Extracts to the directory
function daisy_dec_multi
{
- [[ ! -f $1 ]] && echo "daisy_dec_multi: No input file specified" && return
- [[ ! -d $2 ]] && echo "daisy_dec_multi: No output directory specified" && return
+ arg1=$1
+ arg2=$2
-folder=
-while IFS= read -r line; do
- if [[ "$line" == "daisy_create_folder="* ]];
+ # Handle stdin support
+ if [ ! -t 0 ];
then
- folder=$(echo $line | cut -d "=" -f 2)
- mkdir -p "$2/$folder"
+ arg2=$1
+ arg1=/dev/stdin
fi
- if [[ "$line" == "daisy_folder"* ]];
- then
- folder=$(echo -e $line | cut -d "=" -f 2)
- continue
- fi
+ [[ -t 0 ]] && [[ ! -f $arg1 ]] && echo "daisy_dec_multi: No input file specified" && return
+ [[ ! -d $arg2 ]] && echo "daisy_dec_multi: No output directory specified" && return
- if [[ "$line" == "daisy_data_base64"* ]];
- then
- file=$(echo -e $line | cut -d "_" -f 4- | cut -d "=" -f 1)
- daisy_dec <(echo $line) > "$2/$folder/$file"
- fi
+ folder=
+ while IFS= read -r line; do
+ if [[ "$line" == "daisy_create_folder="* ]];
+ then
+ folder=$(echo $line | cut -d "=" -f 2)
+ echo $folder
+ mkdir -p "$arg2/$folder"
+ fi
- done <<< $(cat "$1")
+ if [[ "$line" == "daisy_folder"* ]];
+ then
+ folder=$(echo -e $line | cut -d "=" -f 2)
+ continue
+ fi
+
+ if [[ "$line" == "daisy_data_base64"* ]];
+ then
+ file=$(echo -e $line | cut -d "_" -f 4- | cut -d "=" -f 1)
+ mkdir -p "$arg2/$folder"
+ daisy_dec <(echo $line) > "$arg2/$folder/$file"
+ fi
+
+ if [[ "$line" == "daisy_perms"* ]];
+ then
+ file=$(echo -e $line | cut -d "_" -f 3- | cut -d "=" -f 1)
+ perms=$(echo -e $line | cut -d "_" -f 3- | cut -d "=" -f 2)
+ chmod $perms "$arg2/$folder/$file"
+ fi
+ done <<< $(cat "$arg1")
}
# Saves a bit on typing
@@ -320,6 +470,23 @@ function grab
awk '{print $'$1'}'
}
+function clip
+{
+ data=""
+
+ if [ ! -t 0 ]; then
+ data="$(cat)"
+ elif [ "$*" != "" ]; then
+ data="$*"
+ else
+ echo $LD_CLIP
+ return 0
+ fi
+
+ # Export the variable
+ export LD_CLIP="$data"
+}
+
function daisy_unalias
{
unalias_param=$@
@@ -338,7 +505,7 @@ function daisy_unalias
# Remove from aliases list
newdata=$(cat "$LD_ALIASFILE" | grep -v "alias $unalias_param")
- bak "$LD_ALIASFILE" 1>/dev/null
+ [[ NO_BAK -lt 1 ]] && bak "$LD_ALIASFILE" 1>/dev/null
echo -e $newdata > "$LD_ALIASFILE"
}
@@ -371,6 +538,60 @@ function daisy_alias
source $LD_ALIASFILE
}
+function daisy_backup
+{
+ for f in `find "$LD_CONFIG_FOLDER" -name "*.src" -type f`;
+ do
+ bak "$f"
+ done
+}
+
+function daisy_clear
+{
+ daisy_backup
+
+ for f in `find "$LD_CONFIG_FOLDER" -name "*.src" -type f`;
+ do
+ echo "Removing config file: $f"
+ rm -rf "$f"
+ done
+
+ echo "Config cleared. Use 'daisy_restore' if you would like to undo this."
+ daisy_reload
+}
+
+function daisy_restore
+{
+ for f in `find "$LD_CONFIG_FOLDER" -name "*.src" -type f`;
+ do
+ unbak "$f"
+ bak "$f" 1>/dev/null
+ done
+
+ echo "Config restored. Backups have been retained."
+ daisy_reload
+}
+
+# Aliases for front-facing daisy_ functions
+function _daisy_def_alias
+{
+ alias ld_$1=daisy_$1
+}
+
+_daisy_def_alias reload
+_daisy_def_alias enc
+_daisy_def_alias enc_multi
+_daisy_def_alias enc_folder
+_daisy_def_alias dec
+_daisy_def_alias dec_multi
+_daisy_def_alias alias
+_daisy_def_alias unalias
+_daisy_def_alias backup
+_daisy_def_alias clear
+_daisy_def_alias restore
+_daisy_def_alias help
+_daisy_def_alias list
+
_daisy_source_configs
###############################################################################
@@ -380,32 +601,11 @@ _daisy_source_configs
# End of user section!
export LD_AVAILABLE=1
-# Start of internal section
-function daisy_quit_if_no
-{
- local dep_name="daisy_has_$1"
- local has_dep="${!dep_name}"
-
- # Check first if we have checked for this dependency, if not, print a fixme!
- # TODO: Remove upon release, or convert into self-modifying code.
- if [[ -z "$has_dep" ]];
- then
- echo "FIXME: Dependency `$1` should have an env variable, checking ad-hoc"
- has_dep=$(daisy_dependency_check $1)
- fi
-
- if [[ $has_dep -eq 0 ]];
- then
- echo "$LD_BIN: The dependency $1 was not found! Please install it" \
- "to be able to use this utility!"
- exit 1
- fi
-}
-
[ -d "$LD_FOLDER" ] && export LD_AVAILABLE=1
# Help function, courtesy of Google Gemini
-function daisy_help() {
+function daisy_help()
+{
local target_tool="$1"
local file="$LD_FOLDER/README.md"
@@ -466,7 +666,8 @@ function daisy_help() {
}
# Courtesy of Google Gemini
-daisy_list() {
+daisy_list()
+{
local file="$LD_FOLDER/README.md"
echo "Available LACKADAISICAL commands:"
@@ -482,16 +683,3 @@ daisy_list() {
}
' | sort
}
-
-# Hide what we don't need
-if [[ ! -v LD_INTERNAL ]];
-then
- unset -f _daisy_source_configs
- unset -f wait_for_editor
- unset -f daisy_quit_if_no
- unset -f daisy_dependency_check
- unset LD_HAS_fzf
- unset LD_HAS_peco
- unset LD_HAS_md5sum
- unset LD_HAS_tree
-fi
\ No newline at end of file
diff --git a/destroy-squash-image b/destroy-squash-image
new file mode 100755
index 0000000..dc4f3a3
--- /dev/null
+++ b/destroy-squash-image
@@ -0,0 +1,27 @@
+#!/bin/bash
+DIR="$@"
+DIR=$(readlink -f "$DIR")
+DIR_SHORT=$(basename $DIR)
+
+if [[ -f "$DIR/.needs_mount" ]];
+then
+ echo "Not a SquashFS image, exiting."
+ exit 0
+fi
+
+echo "Destroying the existing SquashFS image."
+echo "Copying data from the original directory."
+
+echo "Using rsync... in 2 seconds."
+sleep 2
+rsync -avz --progress "$DIR" "/tmp/$DIR_SHORT.tmp"
+
+umount-squash-image "$DIR"
+
+rm -rf "$DIR"
+mv "/tmp/$DIR_SHORT.tmp" "$DIR"
+
+rm -rf "$DIR/../.squashfs/$DIR_SHORT.img"
+rm -rf "$DIR/../.squashfs/$DIR_SHORT"
+
+echo "Your SquashFS image was deleted."
diff --git a/editx b/editx
index 276209f..839dfd2 100755
--- a/editx
+++ b/editx
@@ -1,4 +1,4 @@
-# !/bin/sh
+#!/usr/bin/env bash
# This utility pre-allocs a file and adds execution permissions. It also
# removes the resulting file if it is empty after the editor closes.
diff --git a/filewait b/filewait
index af52929..2705a43 100755
--- a/filewait
+++ b/filewait
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
# A simple utility that waits for a file to become available, infinitely
LD_INTERNAL=1
diff --git a/make-squash-image b/make-squash-image
new file mode 100755
index 0000000..4d33eeb
--- /dev/null
+++ b/make-squash-image
@@ -0,0 +1,88 @@
+#!/bin/bash
+# Lackadaisical squashfs tools
+# Allows you to create a modifiable squashfs-backed image for a folder
+BIN_DIR=$(dirname "$(readlink -f "$0")")
+DIR=$1
+
+test -d "$DIR"
+if [[ $? -ne 0 ]]; then
+ echo Directory "$DIR" does not exist!
+ exit -1
+fi
+
+DIRSIZE=$(du -s "$DIR")
+
+DIR=$(readlink -f "$DIR")
+DIR_SHORT=$(basename "$DIR")
+echo Compressing "$DIR"
+
+# Make basic dirs
+mkdir -p "${DIR}"
+mkdir -p "${DIR_SHORT}"
+
+OVERLAY_ROOT=$(readlink -f "${DIR}/..")/.squashfs/${DIR_SHORT}
+OVERLAY_UPPER=${OVERLAY_ROOT}/upper
+OVERLAY_LOWER=${OVERLAY_ROOT}/lower
+OVERLAY_WORK=${OVERLAY_ROOT}/work
+OVERLAY_TARG=$DIR
+RECREATE=false
+
+echo "Overlay information"
+echo "========================================================================="
+echo "> DIR = \"$DIR\""
+echo "> DIR_SHORT = \"$DIR_SHORT\""
+echo "> OVERLAY_ROOT = \"$OVERLAY_ROOT\""
+echo "> OVERLAY_UPPER = \"$OVERLAY_LOWER\""
+echo "> OVERLAY_LOWER= \"$OVERLAY_UPPER\""
+echo "> OVERLAY_WORK = \"$OVERLAY_WORK\""
+echo "> OVERLAY_TARG = \"$OVERLAY_TARG\""
+echo "========================================================================="
+
+# Make the dirs for the overlay
+mkdir -p "$OVERLAY_ROOT"
+mkdir -p "$OVERLAY_UPPER"
+mkdir -p "$OVERLAY_LOWER"
+mkdir -p "$OVERLAY_WORK"
+mkdir -p "$OVERLAY_TARG"
+
+# Check for existing image
+if test -f "${OVERLAY_ROOT}.img"; then
+ echo "We already have an existing image, updating i..."
+ RECREATE=true
+fi
+
+sudo mksquashfs "$DIR" "${OVERLAY_ROOT}.img.1" -noappend -comp xz
+
+if [ $RECREATE == true ]; then
+ echo "Copy created, now unmount and swap everything."
+ sudo rm -rf "$OVERLAY_UPPER"
+ sudo rm -rf "$OVERLAY_LOWER"
+ sudo rm -rf "$OVERLAY_WORK"
+ rm -rf "${OVERLAY_ROOT}.img"
+fi
+
+mv "${OVERLAY_ROOT}.img.1" "${OVERLAY_ROOT}.img"
+
+# Reset dir
+sudo rm -rf "$DIR"
+mkdir -p "$DIR"
+touch "${DIR}/.needs_mount"
+
+echo "Your SquashFS-backed folder is ready for use."
+echo "To mount it, either cd into it or use mount-squash-image."
+echo "We recomnnend setting up a cronjob for that."
+echo ""
+echo "Should you wish to update the contents of the image with your changes made"
+echo "imside of the folder, simply run make-squash-image again on the same"
+echo "folder to update the imaghe."
+echo
+echo "To disable auto-mounting upon cd, pleas remove the"
+echo "'.needs_mount' file to prevent that."
+echo "To enable mount at-login, add something aking to this to cron:"
+echo "\"@reboot /mount-squash-image \""
+echo
+echo "========================================================================="
+echo "Storage data:"
+echo "Uuncompressed: $DIRSIZE"
+echo " Compressed: $(du -s ${OVERLAY_ROOT}.img)"
+echo "========================================================================="
diff --git a/mount-squash-image b/mount-squash-image
new file mode 100755
index 0000000..d2e065f
--- /dev/null
+++ b/mount-squash-image
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo $@
+
+DIR="$@"
+DIR=$(readlink -f "$DIR")
+DIR_SHORT=$(basename $DIR)
+mkdir -p "$DIR"
+
+OVERLAY_ROOT=$(readlink -f "${DIR}/..")/.squashfs/${DIR_SHORT}
+OVERLAY_UPPER=${OVERLAY_ROOT}/upper
+OVERLAY_LOWER=${OVERLAY_ROOT}/lower
+OVERLAY_WORK=${OVERLAY_ROOT}/work
+OVERLAY_TARG=$DIR
+
+umount-squash-image $@ 1>/dev/null 2>/dev/null
+
+sudo mount "${OVERLAY_ROOT}.img" "$OVERLAY_LOWER" -t squashfs -o loop
+sudo mount -t overlay -o lowerdir="$OVERLAY_LOWER",upperdir="$OVERLAY_UPPER",workdir="$OVERLAY_WORK" none "$OVERLAY_TARG"
+
+echo "SquashFS filesystem is mounted and ready,"
diff --git a/own b/own
index 9d59e2c..84cd6fe 100755
--- a/own
+++ b/own
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
# Simple program that changes ownership to the current
# user, recursively.
@@ -14,4 +14,4 @@ then
exit 2
fi
-sudo chown -R $(whoami):$(whoami) $@
+sudo chown -R $(whoami):$(whoami) "$@"
diff --git a/binbox b/scriptbox
similarity index 58%
rename from binbox
rename to scriptbox
index ec1e474..6aeb03d 100755
--- a/binbox
+++ b/scriptbox
@@ -1,5 +1,5 @@
-#!/bin/sh
-# binbox: Creates a multi-binary script that self-contains the input scripts.
+#!/usr/bin/env bash
+# scriptbox: Creates a multi-binary script that self-contains the input scripts.
# Symlinking to the resulting binary with the name of one of the original scripts will trigger
# said script. The idea is similar to `busybox`.
@@ -11,6 +11,7 @@ args=$@
function help()
{
echo "$LD_BIN is a utility that allows you to generate busybox-style combined binaries."
+ echo "It only supports shell scripts compatible with \`bash\`."
echo "To access the original functionality of an input binary, you can either use a symlink or"
echo "call the function like so: 'combi-bin input-bin ."
echo ""
@@ -55,32 +56,51 @@ i=0
b=0
s=0
p=0
+
while [ $i -lt $# ]; do
case "${args[$i]}" in
-i)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
- inputs+=("${args[$i]}")
+ file="${args[$i]}"
((i++))
- ((b++))
+ if [[ -e "$file" ]]; then
+ inputs+=("$file")
+ ((b++))
+ else
+ echo "WARNING: Missing input binary: \"$file\"."
+ echo "Module will NOT be available!"
+ fi
done
continue
;;
-s)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
- sources+=("${args[$i]}")
+ file="${args[$i]}"
((i++))
- ((s++))
+ if [[ -e "$file" ]]; then
+ sources+=("$file")
+ ((s++))
+ else
+ echo "WARNING: Missing input source: \"$file\"."
+ echo "File will NOT be sourced!"
+ fi
done
continue
;;
-p)
((i++))
while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do
- includes+=("${args[$i]}")
+ file="${args[$i]}"
((i++))
- ((p++))
+ if [[ -e "$file" ]]; then
+ includes+=("$file")
+ ((p++))
+ else
+ echo "WARNING: Missing input include: \"$file\"."
+ echo "File will NOT be included!"
+ fi
done
continue
;;
@@ -97,11 +117,6 @@ echo "Include files: ${includes[*]}"
echo "Source files: ${sources[*]}"
echo "Output binary: $output"
-if [ "$b" -eq 0 ]; then
- echo "Missing input binaries!"
- exit 1
-fi
-
if [[ "$output" == "" ]]; then
echo "Missing output file!"
exit 1
@@ -112,11 +127,16 @@ function add()
echo "$@" >> "$output"
}
+function add_nn()
+{
+ echo -n "$@" >> "$output"
+}
+
rm -rf "$output"
# Now to construct the binary
# >>> Section 1, includes
-add "#!/bin/bash"
+add "#!/usr/bin/env bash"
add "# Multi-call binary generated by LACKADAISICAL binbox"
add "# $output information:"
add "# Contained modules: ${inputs[*]}"
@@ -135,6 +155,7 @@ for f in "${includes[@]}"; do
add "$(cat "$f")"
done
+add "readarray -t all_funcs < <(declare -F | awk '{print \$3}')"
# >>> Section 2: Modules
for f in "${inputs[@]}"; do
@@ -146,25 +167,52 @@ for f in "${inputs[@]}"; do
done
# >>> Section 3: Module selection
+add ""
+add "################################################################################"
+add "# END OF INCLUDED MODULES ######################################################"
+add "################################################################################"
+add ""
+add "# Array of modules as well as array of functions."
+# Add a static list of modules with a no-newline add
+add_nn "modules=("
+ for f in "${inputs[@]}"; do
+ add_nn "\"$f\" "
+ done
+add ")"
+add 'mapfile -t funcs < <(printf "%s\n" "${all_funcs[@]}" "${modules[@]}" "${modules[@]}" | sort | uniq -u)'
+add ""
+add "# Check the export switches (-m and -f)"
+add ""
+
add "symed=1"
add "binself=\$(basename \$0)"
-add "boxfile=\"$output\""
+add "boxfile=\"$(basename $output)\""
+add ""
add "if [[ \$binself == \$boxfile ]]; then"
add " symed=0"
add " if [[ \$# -eq 0 ]]; then"
-add " echo 'Available modules:'"
- for f in "${inputs[@]}"; do
- add " echo '$f'"
- done
+add " echo '$(basename $output): Multi-call binary generated by lackadaisical binbox.'"
+add " echo 'Use switch \"-m\" to generate symlinks of modules in the current directory,'"
+add " echo 'or use switch \"-f\" to generate symlinks of all available functions.'"
+add " echo ''"
+add " echo 'Exported modules:'"
+add " for mod in \"\${modules[@]}\"; do"
+add " echo \"- \$mod\""
+add " done"
+add " echo ''"
+add " echo 'Other functions:'"
+add " for func in \"\${funcs[@]}\"; do"
+add " echo \"- \$func\""
+add " done"
add " exit 0"
add " fi"
add "fi"
-
+add ""
add "if [[ \$symed -eq 0 ]]; then"
add " eval \$@"
add " exit \$?"
add "fi"
-
+add ""
add "if [[ \$symed -eq 1 ]]; then"
add " eval \$(basename \$0) \$@"
add "fi"
diff --git a/shrc b/shrc
index 4e0d0ee..485bfc7 100755
--- a/shrc
+++ b/shrc
@@ -1,4 +1,4 @@
-#!/bin/echo Please run this program with: ". shrc" or include
+#!/usr/bin/env -S echo Please run this program with: ". shrc" or include
# `FROM_RC=1 source shrc` in your RC file to set up an alias.
# Just opens your .rc file easily, for your current shell
@@ -10,37 +10,9 @@ then
LD_INTERNAL=1 source $LD_SOURCE_FILE
fi
-function md5_opt()
-{
- if [[ $daisy_has_md5sum -eq 1 ]];
- then
- echo $(md5sum "$1" | awk '{print $1}')
- fi
-}
+shellname=$(basename $SHELL)
+rc_name="."$shellname"rc"
+rc_path="$HOME/$rc_name"
-if [[ $FROM_RC -eq 1 ]]; then
- alias shrc=". shrc"
-else
- shellname=$(basename $SHELL)
- rc_name="."$shellname"rc"
- rc_path="$HOME/$rc_name"
-
- # Optional MD5 checks
- has_changed=1
- sum1=$(md5_opt "$rc_path")
-
- # This sets a default if the variable does not exist.
- EDITOR=${EDITOR:-$(ched)}
- $EDITOR "$rc_path"
- wait_for_editor $EDITOR "$rc_path"
-
- sum2=$(md5_opt "$rc_path")
-
- if [[ $daisy_has_md5sum -eq 1 && "$sum1" == "$sum2" ]];
- then
- echo "The RC-file $rc_name has not changed on disk. Not sourcing."
- return
- fi
-
- source "$rc_path"
-fi
+daisy_editor "$rc_path"
+source "$rc_path"
diff --git a/sshp b/sshp
new file mode 100755
index 0000000..eeedc7e
--- /dev/null
+++ b/sshp
@@ -0,0 +1,95 @@
+#!/usr/bin/env bash
+
+mounts=()
+ssh_args=()
+remote_port=$((10000 + RANDOM % 10000))
+local_user=$(whoami)
+
+usage()
+{
+ echo "sshp (\"SSH PLUS\") from lackadaisical."
+ echo "Accepts all standard SSH options (see man ssh)."
+ echo "Additionally, supports SSHFS mounts using a Docker-style syntax (-m)."
+ echo "Usage: sshp -m : [user@]host [ssh_options]"
+ echo "Example: sshp -m /home/juli:/home/juli juli@juli.pyon"
+ exit 1
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -m)
+ if [[ -z "$2" ]]
+ then
+ echo "Error: -m requires argument"
+ exit 1
+ fi
+ mounts+=("$2")
+ shift 2
+ ;;
+ *)
+ ssh_args+=("$1")
+ shift
+ ;;
+ esac
+done
+
+if [[ ${#ssh_args[@]} -eq 0 ]]
+then
+ usage
+fi
+
+mount_logic=""
+unmount_logic=""
+
+for map in "${mounts[@]}"; do
+ local_path="${map%%:*}"
+ remote_path="${map##*:}"
+
+ if [[ "$local_path" != /* ]]
+ then
+ local_path="$PWD/$local_path"
+ fi
+
+ mount_logic+="
+ echo '>> Preparing mount: ${remote_path}';
+ if ! mkdir -p \"${remote_path}\" 2>/dev/null
+ then
+ sudo mkdir -p \"${remote_path}\"
+ fi
+
+ if ! sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user ${local_user}@localhost:\"${local_path}\" \"${remote_path}\" 2>/dev/null
+ then
+ echo ' (User mount failed, attempting escalation...)';
+ if ! sudo sshfs -p ${remote_port} -o StrictHostKeyChecking=no,idmap=user,allow_other ${local_user}@localhost:\"${local_path}\" \"${remote_path}\"
+ then
+ echo ' ! Mount failed completely. Check permissions or keys.';
+ fi
+ else
+ echo ' > Mounted successfully.';
+ fi
+ "
+
+ unmount_logic+="
+ fusermount -u -z \"${remote_path}\" 2>/dev/null || sudo fusermount -u -z \"${remote_path}\" 2>/dev/null;
+ "
+done
+
+remote_script="
+ if ! command -v sshfs >/dev/null 2>&1
+ then
+ echo 'WARNING: \"sshfs\" not found on remote host.'
+ echo '>> Skipping mounts, proceeding with shell only...';
+ echo '----------------------------------------------';
+ else
+ ${mount_logic}
+ fi
+
+ ${SHELL:-bash};
+
+ if command -v sshfs >/dev/null 2>&1
+ then
+ ${unmount_logic}
+ fi
+"
+
+ssh -t -R ${remote_port}:localhost:22 "${ssh_args[@]}" "$remote_script"
diff --git a/sw b/sw
index 8427de3..0971413 100755
--- a/sw
+++ b/sw
@@ -1,7 +1,7 @@
-#!/bin/sh
+#!/usr/bin/env bash
# It just swaps two files
-export LD_INTERNAL1
+LD_INTERNAL1
. $(dirname $(realpath $0))/daisy.source
file1=$1
diff --git a/umount-squash-image b/umount-squash-image
new file mode 100755
index 0000000..9eb0522
--- /dev/null
+++ b/umount-squash-image
@@ -0,0 +1,18 @@
+#!/bin/bash
+DIR="$@"
+DIR=$(readlink -f "$DIR")
+DIR_SHORT=$(basename $DIR)
+mkdir -p "$DIR"
+
+OVERLAY_ROOT=$(readlink -f "${DIR}/..")/.squashfs/${DIR_SHORT}
+OVERLAY_UPPER=${OVERLAY_ROOT}/upper
+OVERLAY_LOWER=${OVERLAY_ROOT}/lower
+OVERLAY_WORK=${OVERLAY_ROOT}/work
+OVERLAY_TARG=$DIR
+
+sudo umount -R "$OVERLAY_ROTO"
+sudo umount -R "$OVERLAY_LOWER"
+sudo umount -R "$OVERLAY_TARG"
+sudo umount -R "$DIR"
+
+echo "SquashFS filesystem has been unmounted."
diff --git a/what b/what
index 0bf8c12..b4a470d 100755
--- a/what
+++ b/what
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
# Where is the binary?
# Usage: what []
# Returns: