#!/bin/bash # Multi-call binary generated by LACKADAISICAL binbox # daisy information: # Contained modules: binbox calm cdz editx filewait newday own short shrc sw what # Files included verbatim: daisy.source # Files sourced: # Symlink to this binary with the module name to invoke it, or # use 'daisy ' to do the same. # Included file daisy.source #!/bin/echo "This file can only be sourced, not run stand-alone." -- #!/bin/bash # LACKADAISICAL SOURCE-ABLE FILE # Source this in your RC file or manually to receive some of the simpler # utilities, as well as aliases for `shrc` and `cdf`. Set env variable # FROM_RC to 1 when sourcing this file to get RC-related functionality: # FROM_RC=1 source /daisy.source # This file is also sourced in some of the scripts included within # lackadaisical for common functionality. Some of the shared functionality is # only included if sourced from one of the included scripts, though you are # free to bypass this by setting env variable DAISY_INTERNAL to 1. if [[ $DAISY_INTERNAL -eq 1 ]]; then export DAISY_BIN=$(basename $0) fi # Intro function function daisy_help() { OLD_IFS="$IFS" IFS= echo -e "===================================================================" echo -e "" echo -e "Thanks for installing LACKADAISICAL!" echo -e "This project aims to provide useful utilities as well as learning" echo -e "material." echo -e "" echo -e "It is still under heavy development, not all of the things on this" echo -e "list are present/implemented. Utils marked with * are incomplete." echo -e "" echo -e "===================================================================" echo -e "" echo -e "This suite provides a number of functions, aliases and scripts." echo -e "They are all aimed at enhancing your efficiency." echo -e "" echo -e "===================================================================" echo -e "" echo -e "These are the included binaries:" echo -e " - calm: Reduce a process niceness to 0." echo -e " - cdz: This utility extracts an archive to /tmp and changes" echo -e " directory to it in a new shell instance. Upon exit," echo -e " the files are wiped. If \`archivemount\` is present," echo -e " it will be used to mount the archive instead! You can" echo -e " bypass this behavior by specifying an env value of;" echo -e " NO_ARCHIVEMOUNT=1. The standard script supports zip," echo -e " tarballs, and rar archives. We recommend relying on" echo -e " \`archivemount\` if you have it installed." echo -e " - editx: Uses your standard CLI editor to create/modify a" echo -e " file and make it executable." echo -e " - filewait: This tool is given a filename of a file that does" echo -e " not exist yet. When the file appears on disk, the" echo -e " program quits and simply returns the filename. This" echo -e " can be used in personal workflows." echo -e " - newday: A basic but powerful journaling system. Recommended" echo -e " to set up via crontab. Can be used for everything" echo -e " from diaries to BTRFS snapshots." echo -e " - own: A simple utility. It effectively uses chown -R" echo -e " user:user on its target. Root permissions required!" echo -e " - short: This tool allows you to set up directory shortcuts." echo -e " It enhances cd t to integrate itsef using its own" echo -e " syntax. It is similar to wd." echo -e " - shrc: This tool allows you to edit the RC file for your" echo -e " shell in your preferred editor. After saving, the" echo -e " file is sourced by your shell." echo -e " - sw: A basic function that swaps two files by content." echo -e " Useful for restoring backups." echo -e " - what: This is a tool similar to which and others, the key" echo -e " difference is that it returns partial matches. It can" echo -e " be used to search for binaries." echo -e " -*binbox: This tool can be used to pack bash scripts into one" echo -e " big megascript, much like how \`busybox\` works." echo -e " You can also make symlinks to it to invoke a specific" echo -e " script (current symlinks do not work well)." echo -e "" echo -e "===================================================================" echo -e "" echo -e "There are aliases and functions included within this file as well:" echo -e " - bak/unbak: These small utilities make backups of files by making" echo -e " a copy with a .bak suffix. Unbak reverses the process" echo -e " using sw and removes the backup." echo -e " - lsa: A simple alias for ls -lah." echo -e " - lsn: A simple alias for ls -lah --sort=time --reverse." echo -e " - lss: A simple alias for ls -lah --sort=size --reverse." echo -e " - editbin: An alias for editx $\(which \). Saves on typing." echo -e " - ched: Like chsh but for your editor (EDITOR env). A list" echo -e " from which you can choose an installed editor" echo -e " (CLI or GUI) is shown." echo -e " - cdf: Use fzf to find a file and then cd to its location." echo -e " - ldrc: Edits this file and sources it, similarly to shrc." echo -e " - daisy_init: Alias for directly sourcing this file from any" echo -e " LACKADAISICAL binary. You may use this yourself." echo -e " - daisy_cbin: Contains the name of the current LACKADAISICAL" echo -e " binary being run." echo -e " -*daisy_enc: Converts a file/stdin to a base64 block that can be" echo -e " decoded by passing the output(s) to daisy_dec." echo -e " - *_multi: A version of daisy_enc that runs encodes multiple" echo -e " files and outputs daisy_base64_data blocks to a file" echo -e " or stdout." echo -e " -*daisy_dec: Converts daisy_base64_data blocks back to the form" echo -e " it was in originally." echo -e " - *_multi: A version of daisy_dec that runs on multiple input" echo -e " blocks that are either stored in a file or stdin." echo -e "" echo -e "===================================================================" echo -e "" echo -e "To uninstall LACKADAISICAL, simply remove the source line from your" echo -e "shell RC, and reload it. This does not remove the files!" echo -e "" echo -e "To read this notice again, call the function 'daisy_help'." echo -e "" echo -e "===================================================================" IFS="$OLD_IFS" } # Variables for use in other utilities # Find the right argument for our folder ARG=$0 if [[ ! $ARG == *daisy.source* ]]; then ARG="${BASH_SOURCE[0]}" fi export DAISY_FOLDER=$(dirname $(realpath $ARG)) export DAISY_SOURCE_FILE=$(realpath $ARG) export DAISY_AVAILABLE=0 # Config folder setup export DAISY_CONFIG_FOLDER="$HOME/.config/lackadaisical" NEW_INSTALL=0 if [[ ! -d "$DAISY_CONFIG_FOLDER" ]]; then # Create the folder with its basics mkdir -p "$DAISY_CONFIG_FOLDER" echo "export EDITOR=$EDITOR" > "$DAISY_CONFIG_FOLDER/editor.src" daisy_help NEW_INSTALL=1 fi # Installation into PATH if [[ ! $PATH == *"$DAISY_FOLDER"* ]]; then export PATH="$PATH:$DAISY_FOLDER" [[ NEW_INSTALL -eq 1 ]] && echo -e "Lackadaisical binaries have been added to your PATH variable." fi # Load override from config (default is $EDITOR - so no change is made) _EDITOR=$(cat "$DAISY_CONFIG_FOLDER"/editor.src | grep "EDITOR=" | sed 's/export EDITOR=//g') NEED_CHED=0 if [[ -z $EDITOR ]]; then NEED_CHED=1 fi # Never call if we're in internal mode if [[ $DAISY_INTERNAL -eq 1 ]]; then NEED_CHED=0 fi # Set up the basic alias for `shrc` # Do not set these up if DAISY_INTERNAL=1 is set, or infinite recursion could # occur! if [[ ! -v DAISY_INTERNAL ]]; then alias shrc=". shrc" 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() { cd $(dirname $(fzf)) } # 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=$(which $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 --clear --title "Select Text Editor (Recommendation: nano)" \ --menu "Choose one of the installed text editors:" 15 50 6 \ "${available_editors[@]}" 3>&1 1>&2 2>&3) DIALOG_RET=$? if [ $DIALOG_RET -ne 0 ]; then echo "No editor selected." return fi CHOICE=$(which $CHOICE) echo export EDITOR=$CHOICE > "$DAISY_CONFIG_FOLDER/editor.src" echo export DAISY_OLD_EDITOR=$EDITOR >> "$DAISY_CONFIG_FOLDER/editor.src" # Seems silly but this is also where we should export these source "$DAISY_CONFIG_FOLDER/editor.src" } function wait_for_editor() { pname="$1" fname="$2" # Give some time for a process to launch sleep 1 while true; do ALIVE=$(ps aux | grep $fname | grep $pname) if [[ $ALIVE == "" ]] then break fi sleep 1 done } function ldrc() { FROM_RC=0 $EDITOR "$DAISY_SOURCE_FILE" wait_for_editor $EDITOR "$DAISY_SOURCE_FILE" source "$DAISY_SOURCE_FILE" } function daisy_enc() { has_file=$([[ ! -z $1 ]] && file $1 1>/dev/null; echo $?) has_file=$([[ has_file -eq 0 ]] && echo 1) file_info="no data" file_name="null" if [[ has_file -eq 1 ]]; then file_info=$(file $1) file_name=$(basename $1) fi base64_inner=$(cat ${1:-/dev/stdin} | base64 | tr -d '\n') # Print out our block echo -e "# File info: $file_info" echo -e "daisy_data_base64_$file_name=\"$base64_inner\"" } # Will only take input files, always outputs to stdout function daisy_enc_multi() { [[ ! -d $1 ]] && echo "daisy_dec_multi: No input files specified" && return for file in "$@"; do if [[ -f "$file" ]]; then daisy_enc "$file" echo # separate blocks with a newline else echo "daisy_enc_multi: Skipping non-file: $file" fi done } function daisy_dec() { data=$(cat ${1:-/dev/stdin} | grep -v "#" ) echo -e "$data" | cut -d "=" -f 2- | cut -b 2- | head -c -2 | base64 -d } # Will only take a file and directory, sources it to find all encoded data # 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 declare -a vars=( $(cat $1 | grep -v "# File") ) for enc in "${vars[@]}"; do file=$(echo -e "$enc" | cut -d "_" -f 4- | cut -d "=" -f 1) if [[ ! "$file" == '' ]] then daisy_dec <(echo "$enc") | tee "$2"/"$file" fi done } alias daisy_init='source "$DAISY_SOURCE_FILE"' ############################################################################### # end of FUNCTIONS and ALIASES ################################################ ############################################################################### if [[ $NEED_CHED -eq 1 ]]; then # Editor is unset, pick one, set `vi` as backup TXT1="There is no standard EDITOR environment variable defined. Choose one of the installed text editors." TXT2="You can always change it later wih `ched`, part of the Lackadaisical suite." ched $TXT1 $TXT2 fi # End of user section! export DAISY_AVAILABLE=1 # Start of internal section # Check for dependencies function daisy_dependency_check() { command -v $1 1>/dev/null 2>/dev/null; res=$? echo $(($res ^ 1)) } DAISY_HAS_fzf=$(daisy_dependency_check fzf) DAISY_HAS_md5sum=$(daisy_dependency_check md5sum) function daisy_quit_if_no() { has_dep=$DAISY_HAS_$1 # 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 [[ ! -v DAISY_HAS_$1 ]]; 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 "$DAISY_BIN: The dependency $1 was not found! Please install it" \ "to be able to use this utility!" exit 1 fi } [ -d "$DAISY_FOLDER" ] && export DAISY_AVAILABLE=1 # Source everything in the config folder # We do this at the end so that we do not run into isues for file in "$DAISY_CONFIG_FOLDER"/*; do [ -f "$file" ] && source "$file" done # Module 'binbox': function binbox() { # binbox: 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`. DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source ARGS=$@ function help() { echo "$DAISY_BIN is a utility that allows you to generate busybox-style combined binaries." 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 "" echo "> Usage:" echo "Creating boxed binary: $DAISY_BIN -o <-s source files> <-p include files verbatim> -i INPUT_BINS ..." echo " Unpacking a boxed binary: $DAISY_BIN -e " echo "View this screen: $DAISY_BIN " exit 0 } if [[ $@ == '' ]]; then help fi # Define some building blocks CASE_P1="case $BINARY in" CASE_PM1=" $OPTION)" CASE_PM2=" exec $OTPION_fn" CASE_PM3=" ;;" CASE_CM1=" *)" CASE_CM2=" exec help_fn" CASE_CM3=" ;;" CASE_P2="esac" FUNC_P1="function $OPTION_fn() {" FUNC_P2=" exit($?)" FUNC_P3="}" BASIC_P1="BINARY=$0" # Start parsing args inputs=() output="" inputs=() output="" includes=() sources=() args=("$@") 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]}") ((i++)) ((b++)) done continue ;; -s) ((i++)) while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do sources+=("${args[$i]}") ((i++)) ((s++)) done continue ;; -p) ((i++)) while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do includes+=("${args[$i]}") ((i++)) ((p++)) done continue ;; -o) ((i++)) output="${args[$i]}" ;; esac ((i++)) done echo "Input binaries: ${inputs[*]}" 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 fi function add() { echo "$@" >> "$output" } rm -rf "$output" # Now to construct the binary # >>> Section 1, includes add "# Multi-call binary generated by LACKADAISICAL binbox" add "# $output information:" add "# Contained modules: ${inputs[*]}" add "# Files included verbatim: ${includes[*]}" add "# Files sourced: ${sources[*]}" add "# Symlink to this binary with the module name to invoke it, or" add "# use '$output ' to do the same." for f in "${sources[@]}"; do add ". $f" done for f in "${includes[@]}"; do add "" add "# Included file $f" add "$(cat "$f")" done # >>> Section 2: Modules for f in "${inputs[@]}"; do add "# Module '$f':" add "function $f()" add "{" add "}" done # >>> Section 3: Module selection add "SYMED=1" add "BINSELF=\$(basename \$0)" add "BOXFILE=\"$output\"" 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 " exit 0" add " fi" add "fi" add "if [[ \$SYMED -eq 0 ]]; then" add " eval \$@" add " exit \$?" add "fi" add "if [[ \$SYMED -eq 1 ]]; then" add " eval \$(basename \$0) \$@" add "fi" chmod +x "$output" } # Module 'calm': function calm() { # 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 DAISY_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 BINNY=$pid pid=$NEWPIDS else NEWBINS=$pid BINNY=$(ps -p "$pid" -o comm= 2>/dev/null ) if [ $? != 0 ] then errorFn fi fi echo Calming down $pid \("$BINNY"\)... sudo renice -n 0 -p $pid; done } # Module 'cdz': function cdz() { if [[ $DAISY_INTERNAL -ne 1 ]]; then export DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source fi target=$1 # Check if file exists if [[ -z "$target" ]]; then echo "No target specified." exit 1 fi if ! test -f "$target"; then echo "File not found: \"$target\"" exit 2 fi # Check if archivemount is present which archivemount 1>/dev/null 2>/dev/null hasmounter=$? file "$target" 1>/dev/null exitcode=$? report=$(file "$target") # Check for archive type, supported types are zip/tar/rar comm1=(:) comm2=(echo "Unsupported archive type$add: \"$target\"") comm3=(:) comm4=(:) comm5=(:) echo $report | grep "tar archive" 1>/dev/null istar=$? echo $report | grep "Zip archive" 1>/dev/null iszip=$? echo $report | grep "Android" 1>/dev/null iszip=$? echo $report | grep "RAR archive" 1>/dev/null israr=$? # TAR archives come in many forms, if none of our tests say it's tar # ...but it looks like tar and barks like tar, let's take the shot. # Seems to work fairly well for the record. RES=$(echo "$target" | grep ".tar") if [[ $RES != "" ]]; then istar=0 fi if [[ $NO_ARCHIVEMOUNT -eq 1 ]]; then hasmounter=1 fi if (( $hasmounter == 0 )); then echo "We have \`archivemount\`, so we'll use that!" echo "If you'd prefer we not use it, please specify NO_ARCHIVEMOUNT=1" istar=1 iszip=1 israr=1 fi # Now we set the right command if (( $istar == 0 )); then comm2=(tar xvf "$target" -C) elif (( $iszip == 0 )); then which unzip 1>/dev/null exitcode=$? if (( $exitcode == 0 )); then comm2=(unzip -q "$target" -d) else comm1=(echo "The utility 'unzip' is missing, please install it") comm3=(exit 1) fi elif (( $israr == 0 )); then which unrar 1>/dev/null exitcode=$? if (( exitcode == 0 )); then comm2=(unrar -i nul "$target") else comm1=(echo "The utility 'unrar' is missing, please install it") comm3=(exit 1) fi elif (( $hasmounter == 0 )); then comm2=(archivemount "$target") comm4=(cd ..) comm5=(umount) fi # Create the temp dir, usually dir=$(mktemp -d /tmp/extracted.XXXXXXXX) # And the rest of the commands "${comm1[@]}" "${comm2[@]}" $dir "${comm3[@]}" currentpath=$(realpath .) cd $dir # 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 "Type 'exit' to exit the extracted archive's folder and auto-delete it." eval $SHELL "${comm4[@]}" "${comm5[@]}" $dir rm -rf $dir } # Module 'editx': function editx() { # !/bin/sh # This utility pre-allocs a file and adds execution permissions. It also # removes the resulting file if it is empty after the editor closes. DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source if [[ -z $1 ]]; then echo "No filename specified." exit 2 fi if [[ -z "${EDITOR}" ]]; then ched "EDITOR env variable not set! You will have to set it yourself in the next screen." fi exists=$(file "$1" >/dev/null && echo $?) touch "$1" chmod +x "$1" $EDITOR "$1" wait $! SIZE=$(du "$1" | cut -f 1) if [[ $SIZE -eq 0 && $exists -ne 0 ]]; then rm -rf "$1" fi } # Module 'filewait': function filewait() { # A simple utility that waits for a file to become available, infinitely DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source FILE=$@ while [ ! -f "$FILE" ] do sleep 0.1 done echo $FILE } # Module 'newday': function newday() { # 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/// # It also sets up a symlink in home: $HOME/Today # 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. DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source BINSELF=$(basename $0) DIR_NAME=ByDate ROOT_DIR=$HOME/$DIR_NAME TODAY_SYM=$HOME/Today # Present day TODAY=$(date -I) YEAR=$(echo $TODAY | awk -F"-" '{print $1}') MONTH=$(echo $TODAY | awk -F"-" '{print $2}') DAY=$(echo $TODAY | awk -F"-" '{print $3}') set -e function errorFn() { ERROR=$? if [[ $ERROR -gt 0 ]]; then echo "$BINSELF error ($ERROR): " perl -E 'say $!=shift' $ERROR fi exit $ERROR } # Error handling trap errorFn ERR # First we clear out empty folders, and remove the symlink if it exists test -e "$ROOT_DIR" && find "$ROOT_DIR" -maxdepth 3 -type d -empty -print | xargs rm -rf 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" exitcode=@? } # Module 'own': function own() { # Simple program that changes ownership to the current # user, recursively. DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source if [[ $@ == '' ]]; then echo "$DAISY_BIN: Used to quickly take ownership of files/folders." echo "Requires sudo. If sudo is not installed, this tool will fai." echo "Usage: $DAISY_BIN " echo "Means: chown -R : " exit 2 fi sudo chown -R $(whoami):$(whoami) $@ } # Module 'short': function short() { # short: Creates shortcuts that can be used anywhere. # Can also be used as an alternative for "alias". # # Example usage: # Add a shortcut: short -A dev "/home/john/Development" # Print shortcut content: short dev -> "/home/john/Development" # Remove shortcut: short -D dev # # One could use this to do things like: # cp -R files $(short dev) # cd $(short www) # ssh $(short server) # # Uses a file named .shortcuts in $HOME DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source SHORT_FILE="$DAISY_CONFIG_FOLDER/.shortcuts" } # Module 'shrc': function shrc() { # `FROM_RC=1 source shrc` in your RC file to set up an alias. # Just opens your .rc file easily, for your current shell # and sources the .rc afterwards! # Source standard setup if [[ $DAISY_INTERNAL -ne 1 ]]; then DAISY_INTERNAL=1 source $DAISY_SOURCE_FILE fi function md5_opt() { if [[ $DAISY_HAS_md5sum -eq 1 ]]; then echo $(md5sum "$1" | awk '{print $1}') fi } if [[ $FROM_RC -eq 1 ]]; then alias shrc=". shrc" else BASENAME=$(basename $SHELL) RC_NAME="."$BASENAME"rc" RC_PATH="$HOME/$RC_NAME" # Optional MD5 checks HAS_CHANGED=1 SUM1=$(md5_opt "$RC_PATH") SUM2= # 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 } # Module 'sw': function sw() { # It just swaps two files export DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source FILE1=$1 FILE2=$2 function helpFn() { ERROR=$? if [[ $ERROR -gt 0 ]]; then ERROR_TEXT=$(perl -E 'say $!=shift' $ERROR) echo "$DAISY_BIN error ($ERROR): $ERROR_TEXT" fi echo "Usage: $DAISY_BIN " echo Swap two files in a filesystem. exit $ERROR } if [[ $@ == *"--help"* ]]; then helpFn elif [[ $@ == '' ]]; then echo "No arguments specified." helpFn fi # We set a trap here, together with 'set -e' above, # this makes sure we exit gracefully if we have an # error in one of the ls or mv calls. trap helpFn ERR # We want to swap two files # Easy, but let's be safe about it ls "$FILE1" >/dev/null ls "$FILE2" >/dev/null # Files should exist, now we move mv "$FILE1" "$FILE1.sw" mv "$FILE2" "$FILE2.sw" # We got our moved copies, now we simply rename mv "$FILE1.sw" "$FILE2" mv "$FILE2.sw" "$FILE1" } # Module 'what': function what() { # Where is the binary? # Usage: what [] # Returns: # With no parameters, all visible binaries in PATH. # With parameter, all binaries that match the pattern # given. Accepts default grep patterns, case insensitive # # Examples: # $ what zs.* # pzstd # zsh # zstd # # $ what ftp # ftppass # sftp # vsftpd # # $ what ftp | xargs which # /usr/bin/ftppass # /usr/bin/sftp # /usr/sbin/vsftpd # DAISY_INTERNAL=1 . $(dirname $(realpath $0))/daisy.source PWD=/ ALL_BINS=$(cd / && echo $PATH | sed 's/[:]/ /g' | xargs ls -A | grep -v ":" | sort | uniq) OUTPUT=$(printf '%s\n' "-n" $ALL_BINS | grep -i "$1") echo "$OUTPUT" } SYMED=1 BINSELF=$(basename $0) BOXFILE="daisy" if [[ $BINSELF == $BOXFILE ]]; then SYMED=0 if [[ $# -eq 0 ]]; then echo 'Available modules:' echo 'binbox' echo 'calm' echo 'cdz' echo 'editx' echo 'filewait' echo 'newday' echo 'own' echo 'short' echo 'shrc' echo 'sw' echo 'what' exit 0 fi fi if [[ $SYMED -eq 0 ]]; then eval $@ exit $? fi if [[ $SYMED -eq 1 ]]; then eval $(basename $0) $@ fi