cd "$1"
}
+ # returns true if the variable is an array.
function is_array() {
[[ "$(declare -p $1)" =~ "declare -a" ]]
}
+ # returns true if the name provided is a defined alias.
function is_alias() {
alias $1 &>/dev/null
return $?
}
+ # makes the status of pipe number N (passed as first parameter) into the
+ # main return value (i.e., the value for $?). this is super handy to avoid
+ # repeating the awkward looking code below in multiple places.
+ function promote_pipe_return()
+ {
+ ( exit ${PIPESTATUS[$1]} )
+ }
+
+ ##############
+
+ function fm_username()
+ {
+ # see if we can get the user name from the login name. oddly this sometimes doesn't work.
+ local custom_user="$(logname 2>/dev/null)"
+ if [ -z "$custom_user" ]; then
+ # try the normal unix user variable.
+ custom_user="$USER"
+ fi
+ if [ -z "$custom_user" ]; then
+ # try the windows user variable.
+ custom_user="$USERNAME"
+ fi
+ echo "$custom_user"
+ }
+
+ ##############
+
# displays the value of a variable in bash friendly format.
function var() {
HOLDIFS="$IFS"
IFS="$HOLDIFS"
}
+ ##############
+
# when passed a list of things, this will return the unique items from that list as an echo.
function uniquify()
{
fi
}
+ ##############
+
function success_sound()
{
if [ ! -z "$CLAM_FINISH_SOUND" ]; then
fi
}
+ ##############
+
+ # echoes the maximum number of columns that the terminal supports. usually
+ # anything you print to the terminal with length less than (but not equal to)
+ # maxcols will never wrap.
+ function get_maxcols()
+ {
+ # calculate the number of columsn in the terminal.
+ local cols=$(stty size | awk '{print $2}')
+ echo $cols
+ }
+
+ ##############
+
# checks the result of the last command that was run, and if that failed,
# then this complains and exits from bash. the function parameters are
# used as the message to print as a complaint.
- function test_or_fail()
+ function exit_on_error()
{
if [ $? -ne 0 ]; then
- echo -e "\n\naction failed: $*\n\nExiting script..."
+ echo -e "\n\nan important action failed and this script will stop:\n\n$*\n\n*** Exiting script..."
error_sound
exit 1
fi
}
- # like test_or_fail, but will keep going after complaining.
- function test_or_continue()
+ # like exit_on_error, but will keep going after complaining.
+ function continue_on_error()
{
if [ $? -ne 0 ]; then
- echo -e "\n\nerror occurred: $*\n\nContinuing script..."
+ echo -e "\n\na problem occurred, but we can continue:\n\n$*\n\n=> Continuing script..."
error_sound
fi
}
+ ##############
+
+ # accepts any number of arguments and outputs them to the feisty meow event log.
+ function log_feisty_meow_event()
+ {
+ echo -e "$(date_stringer) -- ${USER}@$(hostname): $*" >> "$FEISTY_MEOW_EVENT_LOG"
+ }
+
+ ##############
+
# wraps secure shell with some parameters we like, most importantly to enable X forwarding.
function ssh()
{
local args=($*)
- save_terminal_title
# we remember the old terminal title, then force the TERM variable to a more generic
# version for the other side (just 'linux'); we don't want the remote side still
# thinking it's running xterm.
- export TERM=linux
+ save_terminal_title
+
+#hmmm: why were we doing this? it scorches the user's logged in session, leaving it without proper terminal handling.
+# # we save the value of TERM; we don't want to leave the user's terminal
+# # brain dead once we come back from this function.
+# local oldterm="$TERM"
+# export TERM=linux
+
/usr/bin/ssh -X -C "${args[@]}"
+
+# # restore the terminal variable also.
+# TERM="$oldterm"
+
restore_terminal_title
+ if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then
+ echo TERM title restored to prior value
+ fi
}
+ ##############
+
# locates a process given a search pattern to match in the process list.
# supports a single command line flag style parameter of "-u USERNAME";
# if the -u flag is found, a username is expected afterwards, and only the
fi
}
+ ##############
+
+#hmmm: holy crowbars, this is an old one. do we ever still have any need of it?
# an unfortunately similarly named function to the above 'ps' as in process
# methods, but this 'ps' stands for postscript. this takes a postscript file
# and converts it into pcl3 printer language and then ships it to the printer.
done
}
-# function fix_alsa() {
-# sudo /etc/init.d/alsasound restart
-# }
+#hmmm: not really doing anything yet; ubuntu seems to have changed from pulseaudio in 17.04?
+ # restarts the sound driver.
+ function fix_sound_driver() {
+ # stop bash complaining about blank function body.
+ local nothing=
+#if alsa something
+# sudo service alsasound restart
+#elif pulse something
+# sudo pulseaudio -k
+# sudo pulseaudio -D
+#else
+# something else...?
+#fi
+
+ }
function screen() {
save_terminal_title
# sudo function wraps the normal sudo by ensuring we replace the terminal
# label if they're doing an su with the sudo.
function sudo() {
-# local first_command="$1"
save_terminal_title
/usr/bin/sudo "$@"
+ retval=$?
restore_terminal_title
# if [ "$first_command" == "su" ]; then
# # yep, they were doing an su, but they're back now.
# label_terminal_with_info
# fi
+ return $retval
}
# trashes the .#blah files that cvs and subversion leave behind when finding conflicts.
echo "The nechung oracle program cannot be found. You may want to consider"
echo "rebuilding the feisty meow applications with this command:"
echo "bash $FEISTY_MEOW_SCRIPTS/generator/produce_feisty_meow.sh"
+ echo
else
$wheres_nechung
fi
unalias CORE_ALIASES_LOADED &>/dev/null
unset -f function_sentinel
# reload feisty meow environment in current shell.
+ log_feisty_meow_event "reloading the feisty meow scripts for $USER in current shell."
source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
# run nechung oracle to give user a new fortune.
nechung
restore_terminal_title
}
- # copies a set of custom scripts into the proper location for feisty meow
- # to merge their functions and aliases with the standard set.
+ # merges a set of custom scripts into the feisty meow environment. can be
+ # passed a name to use as the custom scripts source folder (found on path
+ # $FEISTY_MEOW_SCRIPTS/customize/{name}), or it will try to guess the name
+ # by using the login name.
function recustomize()
{
local custom_user="$1"; shift
if [ -z "$custom_user" ]; then
- # use our default example user if there was no name provided.
- custom_user=fred
+ # default to login name if there was no name provided.
+ custom_user="$(fm_username)"
+ # we do intend to use the login name here to get the login name and to ignore
+ # if the user has sudo root access; we don't want to provide a custom
+ # profile for root.
fi
save_terminal_title
if [ ! -d "$FEISTY_MEOW_SCRIPTS/customize/$custom_user" ]; then
- echo "The customization folder provided for $custom_user should be:"
- echo " '$FEISTY_MEOW_SCRIPTS/customize/$custom_user'"
- echo "but that folder does not exist. Skipping customization."
+ echo -e "the customization folder for '$custom_user' is missing:
+
+ $FEISTY_MEOW_SCRIPTS/customize/$custom_user
+
+we will skip recustomization, but these other customizations are available:
+"
+ # a little tr and sed magic to fix the carriage returns into commas.
+ local line="$(find $FEISTY_MEOW_SCRIPTS/customize -mindepth 1 -maxdepth 1 -type d -exec basename {} ';' | tr '\n' '&' | sed 's/&/, /g' | sed -e 's/, $//')"
+ # make the line feeds and carriage returns manageable with tr.
+ # convert the ampersand, our weird replacement for EOL, with a comma + space in sed.
+ # last touch with sed removes the last comma.
+ echo " $line"
return 1
fi
+
+ # recreate the feisty meow loading dock.
regenerate >/dev/null
- pushd "$FEISTY_MEOW_LOADING_DOCK/custom" &>/dev/null
- incongruous_files="$(bash "$FEISTY_MEOW_SCRIPTS/files/list_non_dupes.sh" "$FEISTY_MEOW_SCRIPTS/customize/$custom_user" "$FEISTY_MEOW_LOADING_DOCK/custom")"
-
- local fail_message="\nare the perl dependencies installed? if you're on ubuntu or debian, try this:\n
- $(grep "apt.*perl" $FEISTY_MEOW_APEX/readme.txt)\n"
-
- #echo "the incongruous files list is: $incongruous_files"
- # disallow a single character result, since we get "*" as result when nothing exists yet.
- if [ ${#incongruous_files} -ge 2 ]; then
- echo "cleaning unknown older overrides..."
- perl "$FEISTY_MEOW_SCRIPTS/files/safedel.pl" $incongruous_files
- test_or_continue "running safedel. $fail_message"
- echo
+
+ # jump into the loading dock and make our custom link.
+ pushd "$FEISTY_MEOW_LOADING_DOCK" &>/dev/null
+ if [ -h custom ]; then
+ # there's an existing link, so remove it.
+ \rm custom
fi
+ # make sure we cleaned up the area before we re-link.
+ if [ -h custom -o -d custom -o -f custom ]; then
+ echo "
+Due to an over-abundance of caution, we are not going to remove an unexpected
+'custom' object found in the file system. This object is located in the
+feisty meow loading dock here: $(pwd)
+And here is a description of the rogue 'custom' object:
+"
+ ls -al custom
+ echo "
+If you are pretty sure that this is just a remnant of an older approach in
+feisty meow, where we copied the custom directory rather than linking it
+(and it most likely is just such a bit of cruft of that nature), then please
+remove that old remnant 'custom' item, for example by saying:
+ /bin/rm -rf \"custom\" ; popd
+Sorry for the interruption, but we want to make sure this removal wasn't
+automatic if there is even a small amount of doubt about the issue."
+ return 1
+ fi
+
+ # create the custom folder as a link to the customizations.
+ ln -s "$FEISTY_MEOW_SCRIPTS/customize/$custom_user" custom
+
popd &>/dev/null
- echo "copying custom overrides for $custom_user"
- mkdir -p "$FEISTY_MEOW_LOADING_DOCK/custom" 2>/dev/null
- perl "$FEISTY_MEOW_SCRIPTS/text/cpdiff.pl" "$FEISTY_MEOW_SCRIPTS/customize/$custom_user" "$FEISTY_MEOW_LOADING_DOCK/custom"
- test_or_continue "running cpdiff. $fail_message"
- if [ -d "$FEISTY_MEOW_SCRIPTS/customize/$custom_user/scripts" ]; then
- echo "copying custom scripts for $custom_user"
- netcp "$FEISTY_MEOW_SCRIPTS/customize/$custom_user/scripts" "$FEISTY_MEOW_LOADING_DOCK/custom/" &>/dev/null
-#hmmm: could save output to show if an error occurs.
- fi
- echo
+ # now take into account all the customizations by regenerating the feisty meow environment.
regenerate
restore_terminal_title
echo $(which $to_find)
}
-#hmmm: improve this by not adding the link
-# if already there, or if the drive is not valid.
function add_cygwin_drive_mounts() {
for i in c d e f g h q z ; do
+#hmmm: improve this by not adding the link if already there, or if the drive is not valid.
ln -s /cygdrive/$i $i
done
}
popd &>/dev/null
}
- function spacem()
- {
- while [ $# -gt 0 ]; do
- arg="$1"; shift
- if [ ! -f "$arg" -a ! -d "$arg" ]; then
- echo "failure to find a file or directory named '$arg'."
- continue
- fi
-
- # first we will capture the output of the character replacement operation for reporting.
- # this is done first since some filenames can't be properly renamed in perl (e.g. if they
- # have pipe characters apparently).
- intermediate_name="$(bash "$FEISTY_MEOW_SCRIPTS/files/replace_spaces_with_underscores.sh" "$arg")"
- local saw_intermediate_result=0
- if [ -z "$intermediate_name" ]; then
- # make sure we report something, if there are no further name changes.
- intermediate_name="'$arg'"
- else
- # now zap the first part of the name off (since original name isn't needed).
- intermediate_name="$(echo $intermediate_name | sed -e 's/.*=> //')"
- saw_intermediate_result=1
- fi
-
- # first we rename the file to be lower case.
- actual_file="$(echo $intermediate_name | sed -e "s/'\([^']*\)'/\1/")"
- final_name="$(perl $FEISTY_MEOW_SCRIPTS/files/renlower.pl "$actual_file")"
- local saw_final_result=0
- if [ -z "$final_name" ]; then
- final_name="$intermediate_name"
- else
- final_name="$(echo $final_name | sed -e 's/.*=> //')"
- saw_final_result=1
- fi
-#echo intermed=$saw_intermediate_result
-#echo final=$saw_final_result
-
- if [[ $saw_intermediate_result != 0 || $saw_final_result != 0 ]]; then
- # printout the combined operation results.
- echo "'$arg' => $final_name"
- fi
- done
- }
-
##############
# new breed of definer functions goes here. still in progress.
# count the number of sub-directories in a directory and echo the result.
function count_directories()
{
- local appsdir="$1"; shift
- numdirs="$(find "$appsdir" -mindepth 1 -maxdepth 1 -type d | wc -l)"
+ local subbydir="$1"; shift
+ numdirs="$(find "$subbydir" -mindepth 1 -maxdepth 1 -type d | wc -l)"
echo $numdirs
}
if [ -d "$src" ]; then
ln -s "$src" "$target"
- test_or_fail "Creating symlink from '$src' to '$target'"
+ exit_on_error "Creating symlink from '$src' to '$target'"
fi
echo "Created symlink from '$src' to '$target'."
}
# pretty prints the json files provided as parameters.
- function json_view()
+ function clean_json()
{
if [ -z "$*" ]; then return; fi
local show_list=()
temp_out="$TMP/$file.view"
cat "$file" | python -m json.tool > "$temp_out"
show_list+=($temp_out)
- test_or_continue "pretty printing '$file'"
+ continue_on_error "pretty printing '$file'"
done
filedump "${show_list[@]}"
rm "${show_list[@]}"
}
+ function json_text()
+ {
+ # only print our special headers or text fields.
+ local CR=$'\r'
+ local LF=$'\n'
+ clean_json $* |
+ grep -i "\"text\":\|^=.*" |
+ sed -e "s/\\\\r/$CR/g" -e "s/\\\\n/\\$LF/g"
+ }
+
+ ##############
+
+ # echoes the machine's hostname. can be used like so:
+ # local my_host=$(get_hostname)
+ function get_hostname()
+ {
+ # there used to be more variation in how to do this, but adopting mingw
+ # and cygwin tools really helped out.
+ local this_host=unknown
+ if [ "$OS" == "Windows_NT" ]; then
+ this_host=$(hostname)
+ elif [ ! -z "$(echo $MACHTYPE | grep apple)" ]; then
+ this_host=$(hostname)
+ elif [ ! -z "$(echo $MACHTYPE | grep suse)" ]; then
+ this_host=$(hostname --long)
+ elif [ -x "$(which hostname 2>/dev/null)" ]; then
+ this_host=$(hostname)
+ fi
+ echo "$this_host"
+ }
+
+ # makes sure that the provided "folder" is a directory and is writable.
+ function test_writeable()
+ {
+ local folder="$1"; shift
+ if [ ! -d "$folder" -o ! -w "$folder" ]; then return 1; fi
+ return 0
+ }
+
+ ##############
+
+ # given a filename and a string to seek and a number of lines, then this
+ # function will remove the first occurrence of a line in the file that
+ # matches the string, and it will also axe the next N lines as specified.
+ function create_chomped_copy_of_file()
+ {
+ local filename="$1"; shift
+ local seeker="$1"; shift
+ local numlines=$1; shift
+
+#echo into create_chomped_copy...
+#var filename seeker numlines
+
+ # make a backup first, oy.
+ \cp -f "$filename" "/tmp/$(basename ${filename}).bkup-${RANDOM}"
+ exit_on_error "backing up file: $filename"
+
+ # make a temp file to write to before we move file into place in bind.
+ local new_version="/tmp/$(basename ${filename}).bkup-${RANDOM}"
+ \rm -f "$new_version"
+ exit_on_error "cleaning out new version of file from: $new_version"
+
+ local line
+ local skip_count=0
+ local found_any=
+ while read line; do
+ # don't bother looking at the lines if we're already in skip mode.
+ if [[ $skip_count == 0 ]]; then
+ # find the string they're seeking.
+ if [[ ! "$line" =~ .*${seeker}.* ]]; then
+ # no match.
+ echo "$line" >> "$new_version"
+ else
+ # a match! start skipping. we will delete this line and the next N lines.
+ ((skip_count++))
+#echo first skip count is now $skip_count
+ found_any=yes
+ fi
+ else
+ # we're already skipping. let's keep going until we hit the limit.
+ ((skip_count++))
+#echo ongoing skip count is now $skip_count
+ if (( $skip_count > $numlines )); then
+ echo "Done skipping, and back to writing output file."
+ skip_count=0
+ fi
+ fi
+ done < "$filename"
+
+#echo file we created looks like this:
+#cat "$new_version"
+
+ if [ ! -z "$found_any" ]; then
+ # put the file back into place under the original name.
+ \mv "$new_version" "$filename"
+ exit_on_error "moving the new version into place in: $filename"
+ else
+ # cannot always be considered an error, but we can at least gripe.
+ echo "Did not find any matches for seeker '$seeker' in file: $filename"
+ fi
+ }
+
+ ##############
+
+ # space 'em all: fixes naming for all of the files of the appropriate types
+ # in the directories specified.
+ function spacemall() {
+ local -a dirs=("${@}")
+ if [ ${#dirs[@]} -eq 0 ]; then
+ dirs=(.)
+ fi
+
+ local charnfile="$(mktemp $TMP/zz_charn.XXXXXX)"
+ find "${dirs[@]}" -follow -maxdepth 1 -mindepth 1 -type f | \
+ grep -i \
+"docx\|eml\|html\|jpeg\|jpg\|m4a\|mov\|mp3\|ods\|odt\|pdf\|png\|pptx\|txt\|xlsx\|zip" | \
+ sed -e 's/^/"/' | sed -e 's/$/"/' | \
+ xargs bash "$FEISTY_MEOW_SCRIPTS/files/spacem.sh"
+ # drop the temp file now that we're done.
+ rm "$charnfile"
+ }
+
+ ##############
+
+ # site avenger aliases
+ function switchto()
+ {
+ THISDIR="$FEISTY_MEOW_SCRIPTS/site_avenger"
+ source "$FEISTY_MEOW_SCRIPTS/site_avenger/shared_site_mgr.sh"
+ switch_to "$1"
+ }
+
##############
# NOTE: no more function definitions are allowed after this point.
echo running tests on set_var_if_undefined.
flagrant=petunia
set_var_if_undefined flagrant forknordle
- test_or_fail "testing if defined variable would be whacked"
+ exit_on_error "testing if defined variable would be whacked"
if [ $flagrant != petunia ]; then
echo set_var_if_undefined failed to leave the test variable alone
exit 1