Latest version

This commit is contained in:
Sam Hardeman 2026-03-08 20:54:07 +01:00
parent e3a2efdb43
commit eb0aab1613
17 changed files with 815 additions and 328 deletions

View file

@ -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 <dir> -> .daisy/<dir>/<year>/<month>/<day>.
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 <data>" 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 ---
```

View file

@ -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/<Year>/<Month>/<Day>
# $HOME/<Tag>/<Year>/<Month>/<Day>
# 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 <folder>"
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/<year>/<month>/<day>'."
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=@?

41
calm
View file

@ -1,41 +0,0 @@
#!/bin/sh
# Calm a process down
# NEEDS_WORK: cleanup
# calm <pid> == only one process
# calm <bin> == 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 <pid> <bin> .... 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

22
cdz
View file

@ -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"

View file

@ -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: <file>
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: <file>
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

27
destroy-squash-image Executable file
View file

@ -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."

2
editx
View file

@ -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.

View file

@ -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

88
make-squash-image Executable file
View file

@ -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 <path>/mount-squash-image <folder>\""
echo
echo "========================================================================="
echo "Storage data:"
echo "Uuncompressed: $DIRSIZE"
echo " Compressed: $(du -s ${OVERLAY_ROOT}.img)"
echo "========================================================================="

20
mount-squash-image Executable file
View file

@ -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,"

4
own
View file

@ -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) "$@"

View file

@ -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 <input-bin args>."
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"

40
shrc
View file

@ -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"

95
sshp Executable file
View file

@ -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 <local>:<remote> [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"

4
sw
View file

@ -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

18
umount-squash-image Executable file
View file

@ -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."

2
what
View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash
# Where is the binary?
# Usage: what [<keyword>]
# Returns: