From 1d5e9386bd6453098b048a4a8610cb126ae23d74 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sun, 27 Nov 2022 04:38:45 -0800 Subject: [PATCH 01/47] Auto TAB completion for bash using alias for occ. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 330 ++++++++++++++++++++++++++++++++++++++++++++++ complete.occ | 148 +++++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100755 bash-add-alias.sh create mode 100644 complete.occ diff --git a/bash-add-alias.sh b/bash-add-alias.sh new file mode 100755 index 0000000000000..85472aac11f23 --- /dev/null +++ b/bash-add-alias.sh @@ -0,0 +1,330 @@ +#!/bin/bash + +## ########################################################################### +## Creates an alias to run `occ` as the appropriate web server user +## +## Optionally adds the alias to user's .bash_aliases file +## Optionally adds the alias to SUDO_USER's .bash_aliases file +## Verifies `occ` is owned by web server user +## Optionally copies bash completion script `complete.occ` to +## /etc/bash_completion.d/ +## +## Ronald Barnes (c) 2022 +## ########################################################################### + + +## Dubugging: +## set -x +## Errors exit immediately: +## set -e +## Catch undefined vars: +set -u + + +## Define colours: +function define_colours() + { + green="\e[1;32m" + yellow='\e[1;33m' + red='\e[1;31m' + default_colour="\e[00m" + } + + +## Leave no trace after exit (except alias(es)): +function cleanup_vars() + { + unset value + unset httpdUser + unset user_name + unset home_dir + unset aliasExists + unset phpFound + unset answer + unset aliasString + unset addAlias + unset aliasExists + + unset getHttpdUser_old + unset getHttpdUser + unset occOwner + unset occPath + unset getOccPath + unset script_found + + unset green + unset yellow + unset red + unset default_colour + + ## Reset all trap signals: + trap - SIGINT + trap - SIGHUP + trap - SIGTERM + trap - SIGKILL + trap - EXIT + trap - QUIT + ## If param was passed, i.e. "ALL", cleanup EVERYTHING, we're done: + if [[ ${#@} -ge 1 ]]; then + trap - RETURN + unset cleanup_vars + ## Reset unbound var checking, else i.e. bash completion breaks, etc. + set +u + unset define_colours + fi + ## Reset unbound var checking, else i.e. bash completion breaks, etc. +# set +u + ## This hangs around if run via ". $this_script" and needs to be + ## manually cleared. + ## Putting *entire* script (after func defs) inside subshell fixed it: +# trap - RETURN +# trap -p + } + +function getHttpdUser() + { + ## Fetch possible httpd users (for sudo -u ...) into array: + ## + ## Params: regex / string of name(s) to search for + while read value; do + ## Associative array: + ## httpdUser[$value]=$value + ## Normal, indexed array: + httpdUser+=($value) + done <<< $(grep \ + --extended-regex \ + --ignore-case \ + --only-matching \ + --max-count=1 \ + "${1}" /etc/passwd \ + ) + } + + + + +function getOccPath() + { + read -ep "Path to file 'occ': " -i "/" occPath + if [[ ! -f ${occPath} ]] ; then + getOccPath + fi + ## echo "occPath: \"${occPath}\"" + } + + +function bash_aliases() + { + if [[ $# -eq 0 ]] ; then + ## Expecting path to .bash_aliases directory + return 99 + else + home_dir=${1} + fi + + grep --no-messages "occ" ${home_dir}/.bash_aliases + aliasExists=$? + if [[ aliasExists -eq 0 ]]; then + echo "There is an \"occ\" alias in ${home_dir}.bash_aliases:" + grep "occ" ${home_dir}/.bash_aliases + elif [[ -w ${home_dir}/.bash_aliases ]]; then + echo -en "Add alias to ${yellow}${home_dir}/.bash_aliases${default_colour}?" + read -s -p " (y/N) " -n 1 answer + if [[ ${answer} =~ ^Y|y ]] ; then + echo "Y" + echo "${aliasString}" >> ${home_dir}/.bash_aliases + answer=$? + if [[ ${answer} -eq 0 ]] ; then + echo -ne "${green}Success${default_colour}: " + grep occ ${home_dir}/.bash_aliases + fi + else + ## if [[ ${answer} != "" ]] ; then + echo "N" + fi + else + echo -ne "${yellow}NOTICE${default_colour}: Cannot access " + echo -e "${home_dir}/.bash_aliases" + fi + } + + + + +## Run EVERYTHING in a subshell so "trap ... RETURN" doesn't linger: +## ( +## Cleanup all variables on exit: +## trap 'cleanup_vars' SIGINT SIGKILL SIGTERM +## Cleanup ALL variables on exit (including cleanup_vars() itself): +trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM + + +## Handy red / yellow / green / default colour defs: +define_colours + +## Store web server user name(s) from /etc/passwd as indexed array: +## declare -A httpdUser +declare -a httpdUser + +## Find the web server user name: +getHttpdUser "httpd|www-data" +if [ ${#httpdUser[0]} -eq 0 ] ; then + ## No standard httpd user found, try "nobody": + getHttpdUser "nobody" +fi + + +if [ ${#httpdUser[0]} -eq 0 ] ; then + echo -e "${red}ERROR${default_colour}: No web server user found." + ## kill -s SIGINT $$ + return 1 +else + echo -ne "Web server user name: " + echo -e "\"${green}${httpdUser[0]}${default_colour}\"." +fi + + +## Looks for existing occ alias: +occPath="" +alias occ 2>/dev/null +aliasExists=$? +## USER=root, HOME=/root, SUDO_USER=me: +## user_name=${SUDO_USER:-$USER} +user_name=${USER:-$SUDO_USER} +if [ ${aliasExists} -eq 0 ] ; then + echo "Alias for occ found for user \"${user_name}\"." + aliasString=$(alias occ) + occPath=${aliasString##* } +else + echo "Alias for occ command not found for user \"${user_name}\"." + which php 2>&1 > /dev/null + phpFound=$? + if [ $phpFound -ne 0 ]; then + echo -e "${red}ERROR${default_colour}: php not found in path." + kill -s SIGKILL $$ + fi + occPath="$(pwd)/occ" + if [[ -f ${occPath} ]] ; then + occPath=$(pwd)/occ + else + echo "Can't find \"occ\", not in current directory." + getOccPath + fi + occOwner=$(stat --format="%U" ${occPath}) + if [[ ${occOwner} != ${httpdUser[0]} ]] ; then + echo -e "${red}ERROR${default_colour}: Owner of occ is not web server user:" + echo " ${occOwner} != ${httpdUser}" + ## kill -s SIGKILL $$ + kill -s SIGINT $$ + trap - RETURN + return 99 + fi + + aliasString="occ='sudo --user ${httpdUser} php ${occPath}'" + echo -ne "Run \"${yellow}alias ${green}${aliasString}${default_colour}\"" + read -s -p " (y/N)? " -n 1 answer + if [[ ${answer} =~ ^[Yy] ]] ; then + echo "Y" + eval alias "${aliasString}" + alias occ +## elif [[ ${answer} != "" ]] ; then + else + echo "N" + fi +fi + +## Is there an occ alias in ~/.bash_aliases? +bash_aliases $HOME +home_dir="" +if [[ "${SUDO_USER}" != "" ]] ; then + ## Find user-who-ran-sudo's home directory: + home_dir=$(grep ${SUDO_USER} /etc/passwd) + ## Strip off colon->end-of-line + home_dir=${home_dir%:*} + ## Strip off start-of-line->last colon: + home_dir=${home_dir##*:} + if [[ "$HOME" != "${home_dir}" ]] ; then + bash_aliases ${home_dir} + fi +fi + + +## Run complete.occ to handle bash auto completion? +script_found=1 ## aka False +## Strip "occ" from occPath: +occPath=${occPath%/*} +if [[ -f ${occPath}/complete.occ ]] ; then + script_found=0 + echo -en "Run bash completion script " + echo -en "${green}complete.occ${default_colour}? " + read -sp " (Y/n) " -N 1 answer + if [[ ${answer} =~ ^[Nn] ]] ; then + echo "N" + else + echo "Y" + echo -n "Running ${occPath}/complete.occ ... " + ## Do not run cleanup_vars() when complete.occ returns: + trap - RETURN + source ${occPath}/complete.occ + ## Reset trap: + trap 'cleanup_vars ALL' RETURN + status=$? + if [[ ${status} -eq 0 ]] ; then + echo -e "${green}success${default_colour}." + else + echo -e "${red}Error${default_colour}." + fi + fi +fi + + +## Does `complete.occ` exist in /etc/bash_completion.d/? +## Does `complete.occ` exist in /usr/share/bash-completion/completions/? +## If neither, add it to /etc/bash_completion.d/? +if [[ -d /etc/bash_completion.d ]] ; then + if [[ -f /etc/bash_completion.d/complete.occ ]] ; then + script_found=0 + echo "Found existing complete.occ in /etc/bash_completion.d/" + else + if [[ -f ${occPath}/complete.occ ]] ; then + echo -en "Add ${yellow}complete.occ${default_colour} " + echo -en "to /etc/bash_completion.d?" + read -sp " (y/N) " -n 1 answer + if [[ ${answer} =~ ^[Yy] ]] ; then + echo "Y" +# ( + cp -v complete.occ /etc/bash_completion.d + if [[ $? -ne 0 ]] ; then + echo -ne "${red}ERROR${default_colour}: Could not " + echo -e "copy complete.occ to /etc/bash_completion.d/" + else + ## Copy successful, set owner and permissions: + chown -v root:root /etc/bash_completion.d/complete.occ + chmod -v 0644 /etc/bash_completion.d/complete.occ + fi +# ) + else + echo "N" + fi + fi +# elif [[ -d /usr/share/bash-completion ]] ; then +# if [[ -f /usr/share/bash-completion/completions/complete.occ ]] ; then +# script_found=0 +# echo -n "Found existing complete.occ in " +# echo "/usr/share//bash-completion/completions" +# fi +# fi + fi +fi + + + +## Cannot remove trap on RETURN inside a return trap catch, so do it here: +trap - RETURN +## Now clean all vars and remove all traps +cleanup_vars ALL +trap -p RETURN +echo "DONE." +## echo "Run \"trap -p\" to see if there's an existing trap on return" +## echo "If so, run \"trap - RETURN\" to clear it." +## ) ## end sub-shell diff --git a/complete.occ b/complete.occ new file mode 100644 index 0000000000000..6eebc8fec7305 --- /dev/null +++ b/complete.occ @@ -0,0 +1,148 @@ +#!/bin/bash + +## ########################################################################### +## Place this file in /etc/bash_completion.d so that +## it can get processed each time a new bash session is run. +## +## Ensure it is owned by root:root (chown -v root:root thisFileName +## Also, only root can edit it: (chmod -v 0644 thisFileName) +## +## You may need to install bash-completion package, i.e.: +## sudo apt install bash-completion +## +## (c) Ronald Barnes 2022 +## ########################################################################### +## +## NOTE: for best bash_completion experience, add the following lines to +## ~/.inputrc or /etc/inputrc: +## from "man readline": +set colored-completion-prefix on +set colored-stats on + + + + + +## Get list of options beginning with "-", i.e. --help, --verbose, etc.: +function get_opts_list() + { + ## Read the \n-delimited list into an array: + while read -r value; do + opts_list+=("${value}") + ## Read output of "occ" and get word-chars following "-" or "--": + done <<< $(occ | + grep --extended-regex --only-matching " \-(\-|\w)+" + ) + ## Verbose settings hard to parse: i.e. "-v|vv|vvv, --verbose" + ## Just manually add -vv and -vvv, and place in order (after -v): + local len + ((len=${#opts_list[@]}-1)) + opts_list[len]="-vv" + opts_list+=("-vvv") + opts_list+=("--verbose") + } + + + + +## This runs the completions for "occ" command, which is an alias to: +## sudo -u $web_server_user php occ +function _occ() + { + ## Word being inspected (CWORD==Current WORD, COMP_CWORD is index): + local CWORD=${COMP_WORDS[COMP_CWORD]} + ## Previous Word being inspected (PWORD==Previous WORD): + local PWORD=${COMP_WORDS[COMP_CWORD-1]} + + ## Change word break chars to exclude ":" and "-", since occ uses them: + COMP_WORDBREAKS=${COMP_WORDBREAKS/:/} + COMP_WORDBREAKS=${COMP_WORDBREAKS/-/} + + ## Default is word list, but "index" requires a file name, let readline + ## handle that, per + ## 'https://stackoverflow.com/questions/12933362/getting-compgen-to-include-slashes-on-directories-when-looking-for-files/19062943#19062943' + compgen_skip="no" + compopt +o default + ## Since ":" is valid, and requires further sub-args, add NO SPACEs to end: + compopt -o nospace + + ## Put the options to present to user into this: + declare -a display_args_arr + + ## Parse out options (all start with "-" or "--"): + declare -a opts_list + + ## List of all args returned by running "occ", minus options that begin + ## with "-": + declare -a occ_args_arr + + ## temp storage to parse to array: + local occ_args + + + + ## Gather all valid args reported by running "occ": + while read -r occ_args ; do + if [[ ${occ_args} != command && ${occ_args:0:1} != - ]]; then + ## "command" is section heading, not valid arg: + ## Skip switches that begin with "-": + occ_args_arr+=("${occ_args}") + fi + done <<< $(occ --raw 2>&1| + ## Starts with alpha-numerics, can include colons and/or hyphens: + grep --extended-regex --only-matching "^[[:alnum:]:-]+" + ) + + + + ## Check for hyphen / dash / "-" as first char, if so, get options list: + if [[ ${CWORD:0:1} == - ]] ; then + get_opts_list + display_args_arr=${opts_list[@]} + + ## If this is first word (after "occ"), shorten list of valid choices + ## by stripping everything after first ":" + ## There can easily be 180+ options otherwise! + ## Note: there's always an empty second array element after "occ": + ## Test for incomplete word by seeking colons: + elif [[ ! ${CWORD} =~ : ]]; then + ## Use associative array to get *unique* values: + declare -A short_list_args_arr + local X + for (( X=0 ; X<${#occ_args_arr[@]} ; X++ )); do + ## Here's the find/replace of colon -> end-of-line with just colon (:): + local value="${occ_args_arr[X]/:*/:}" + ## Here's the de-duplication via associate array: + short_list_args_arr[$value]=$value + done + display_args_arr=${short_list_args_arr[@]} + else + ## So far, line consists of "occ ..." i.e. something more than "occ" + ## See what matches CWORD + local X + for (( X=0 ; X<${#occ_args_arr[@]} ; X++ )); do + ## Add only args that match current word: + if [[ ${occ_args_arr[X]} =~ ^${CWORD} ]] ; then + local value="${occ_args_arr[X]}" + display_args_arr+=("${value}") + fi + done + fi + + + local candidates=$(compgen -W "${display_args_arr[*]}" -- "${CWORD}") + ## When no matches, or an option takes a list of files, support + ## readline's default behaviour of completing files/directories: + ## (may not apply to occ options, or ... maybe there is one I haven't seen) + if [ ${#candidates[@]} -eq 0 ] || [ "${compgen_skip}" == "yes" ]; then + compopt -o default + COMPREPLY=() + else + COMPREPLY=($(printf '%s' "${candidates[@]}")) + fi + + ## TAB=9, ALT+?=63,... + ## echo "COMP_TYPE: \"${COMP_TYPE}\"" + } + +complete -F _occ occ From 18f445d77af10b018cb9d24e448694e3466cc074 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sun, 27 Nov 2022 13:22:45 -0800 Subject: [PATCH 02/47] Updated copyright per Contribution guidelines. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 2 +- complete.occ | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 85472aac11f23..4132096bc8031 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -9,7 +9,7 @@ ## Optionally copies bash completion script `complete.occ` to ## /etc/bash_completion.d/ ## -## Ronald Barnes (c) 2022 +## @copyright Copyright © 2022, Ronald Barnes (ron@ronaldbarnes.ca) ## ########################################################################### diff --git a/complete.occ b/complete.occ index 6eebc8fec7305..67b1bd44b5e4f 100644 --- a/complete.occ +++ b/complete.occ @@ -10,7 +10,7 @@ ## You may need to install bash-completion package, i.e.: ## sudo apt install bash-completion ## -## (c) Ronald Barnes 2022 +## @copyright Copyright © 2022, Ronald Barnes (ron@ronaldbarnes.ca) ## ########################################################################### ## ## NOTE: for best bash_completion experience, add the following lines to From 102052eab2eafa33c464a5e749dc6ef023ded887 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 28 Nov 2022 03:59:26 -0800 Subject: [PATCH 03/47] Resolved requested changes to PR. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 4132096bc8031..173a6abea3815 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -72,23 +72,21 @@ function cleanup_vars() set +u unset define_colours fi - ## Reset unbound var checking, else i.e. bash completion breaks, etc. -# set +u - ## This hangs around if run via ". $this_script" and needs to be - ## manually cleared. - ## Putting *entire* script (after func defs) inside subshell fixed it: -# trap - RETURN -# trap -p } -function getHttpdUser() +function searchHttpdUser() { + if [[ $# -eq 0 ]] ; then + ## Expecting user name to search for + return 99 + else + searchUser=${1} + fi + ## Fetch possible httpd users (for sudo -u ...) into array: ## ## Params: regex / string of name(s) to search for while read value; do - ## Associative array: - ## httpdUser[$value]=$value ## Normal, indexed array: httpdUser+=($value) done <<< $(grep \ @@ -96,7 +94,7 @@ function getHttpdUser() --ignore-case \ --only-matching \ --max-count=1 \ - "${1}" /etc/passwd \ + "${searchUser}" /etc/passwd \ ) } @@ -109,7 +107,6 @@ function getOccPath() if [[ ! -f ${occPath} ]] ; then getOccPath fi - ## echo "occPath: \"${occPath}\"" } @@ -139,7 +136,6 @@ function bash_aliases() grep occ ${home_dir}/.bash_aliases fi else - ## if [[ ${answer} != "" ]] ; then echo "N" fi else @@ -151,11 +147,6 @@ function bash_aliases() -## Run EVERYTHING in a subshell so "trap ... RETURN" doesn't linger: -## ( -## Cleanup all variables on exit: -## trap 'cleanup_vars' SIGINT SIGKILL SIGTERM -## Cleanup ALL variables on exit (including cleanup_vars() itself): trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM @@ -292,7 +283,6 @@ if [[ -d /etc/bash_completion.d ]] ; then read -sp " (y/N) " -n 1 answer if [[ ${answer} =~ ^[Yy] ]] ; then echo "Y" -# ( cp -v complete.occ /etc/bash_completion.d if [[ $? -ne 0 ]] ; then echo -ne "${red}ERROR${default_colour}: Could not " @@ -302,18 +292,10 @@ if [[ -d /etc/bash_completion.d ]] ; then chown -v root:root /etc/bash_completion.d/complete.occ chmod -v 0644 /etc/bash_completion.d/complete.occ fi -# ) else echo "N" fi fi -# elif [[ -d /usr/share/bash-completion ]] ; then -# if [[ -f /usr/share/bash-completion/completions/complete.occ ]] ; then -# script_found=0 -# echo -n "Found existing complete.occ in " -# echo "/usr/share//bash-completion/completions" -# fi -# fi fi fi @@ -325,6 +307,3 @@ trap - RETURN cleanup_vars ALL trap -p RETURN echo "DONE." -## echo "Run \"trap -p\" to see if there's an existing trap on return" -## echo "If so, run \"trap - RETURN\" to clear it." -## ) ## end sub-shell From 8e876483315699f90b3e1d24db5103e0532c39d3 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 28 Nov 2022 04:20:55 -0800 Subject: [PATCH 04/47] Resolved one more comment deletion, per PR change request(s). Signed-off-by: Ronald Barnes --- complete.occ | 3 --- 1 file changed, 3 deletions(-) diff --git a/complete.occ b/complete.occ index 67b1bd44b5e4f..878959d7270a0 100644 --- a/complete.occ +++ b/complete.occ @@ -140,9 +140,6 @@ function _occ() else COMPREPLY=($(printf '%s' "${candidates[@]}")) fi - - ## TAB=9, ALT+?=63,... - ## echo "COMP_TYPE: \"${COMP_TYPE}\"" } complete -F _occ occ From 56dfa43d7ea9c90ab08d76d94877101193ca5455 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 28 Nov 2022 05:02:46 -0800 Subject: [PATCH 05/47] Changed getHttpdUser to searchHttpdUser through-out, per PR change requests. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 173a6abea3815..3510c0b668ced 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -45,8 +45,7 @@ function cleanup_vars() unset addAlias unset aliasExists - unset getHttpdUser_old - unset getHttpdUser + unset searchHttpdUser unset occOwner unset occPath unset getOccPath @@ -154,14 +153,13 @@ trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM define_colours ## Store web server user name(s) from /etc/passwd as indexed array: -## declare -A httpdUser declare -a httpdUser ## Find the web server user name: -getHttpdUser "httpd|www-data" +searchHttpdUser "httpd|www-data" if [ ${#httpdUser[0]} -eq 0 ] ; then ## No standard httpd user found, try "nobody": - getHttpdUser "nobody" + searchHttpdUser "nobody" fi From 8de4ac187b1a7d47aa6cbb92a5ea607fda3a2143 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 30 Nov 2022 23:11:39 -0800 Subject: [PATCH 06/47] Revised per pull request comment https://github.com/nextcloud/server/pull/35451#discussion_r1033380070 as the 'complete' built-in handles de-duplication and sortation. Signed-off-by: Ronald Barnes --- complete.occ | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/complete.occ b/complete.occ index 878959d7270a0..10b74ea6d3385 100644 --- a/complete.occ +++ b/complete.occ @@ -35,11 +35,9 @@ function get_opts_list() ) ## Verbose settings hard to parse: i.e. "-v|vv|vvv, --verbose" ## Just manually add -vv and -vvv, and place in order (after -v): - local len - ((len=${#opts_list[@]}-1)) + ## Note: `complete` built-in handles de-duplication and sortation opts_list[len]="-vv" opts_list+=("-vvv") - opts_list+=("--verbose") } From 8e99a605bec7a051e19ea2d8e24a1475681863cc Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 1 Dec 2022 00:14:48 -0800 Subject: [PATCH 07/47] Reset COMP_WORDBREAKS to original value when finished. Add space after completed word unless it contains a colon. Signed-off-by: Ronald Barnes --- complete.occ | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/complete.occ b/complete.occ index 10b74ea6d3385..486e44ce5b3a2 100644 --- a/complete.occ +++ b/complete.occ @@ -53,6 +53,7 @@ function _occ() local PWORD=${COMP_WORDS[COMP_CWORD-1]} ## Change word break chars to exclude ":" and "-", since occ uses them: + COMP_WORDBREAKS_ORIG=${COMP_WORDBREAKS} COMP_WORDBREAKS=${COMP_WORDBREAKS/:/} COMP_WORDBREAKS=${COMP_WORDBREAKS/-/} @@ -62,7 +63,7 @@ function _occ() compgen_skip="no" compopt +o default ## Since ":" is valid, and requires further sub-args, add NO SPACEs to end: - compopt -o nospace + compopt +o nospace ## Put the options to present to user into this: declare -a display_args_arr @@ -114,6 +115,8 @@ function _occ() short_list_args_arr[$value]=$value done display_args_arr=${short_list_args_arr[@]} + ## Since ":" is valid, and requires further sub-args, add NO SPACEs to end: + compopt -o nospace else ## So far, line consists of "occ ..." i.e. something more than "occ" ## See what matches CWORD @@ -138,6 +141,10 @@ function _occ() else COMPREPLY=($(printf '%s' "${candidates[@]}")) fi + + ## Reset word-break chars: + COMP_WORDBREAKS=${COMP_WORDBREAKS_ORIG} + unset COMP_WORDBREAKS_ORIG } complete -F _occ occ From 2d091e2352efbbe80f24136675448007c7feaf34 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 1 Dec 2022 02:19:36 -0800 Subject: [PATCH 08/47] Add quotes around COMP_WORDBREAKS, else unexpected behaviour. Signed-off-by: Ronald Barnes --- complete.occ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/complete.occ b/complete.occ index 486e44ce5b3a2..60b4c4c17846b 100644 --- a/complete.occ +++ b/complete.occ @@ -53,7 +53,7 @@ function _occ() local PWORD=${COMP_WORDS[COMP_CWORD-1]} ## Change word break chars to exclude ":" and "-", since occ uses them: - COMP_WORDBREAKS_ORIG=${COMP_WORDBREAKS} + COMP_WORDBREAKS_ORIG="${COMP_WORDBREAKS}" COMP_WORDBREAKS=${COMP_WORDBREAKS/:/} COMP_WORDBREAKS=${COMP_WORDBREAKS/-/} From 2aa494013227029be9e80e09d9b1fb06048c0a5e Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 1 Dec 2022 20:31:04 -0800 Subject: [PATCH 09/47] Fixed adding '-vv' option to array: remnant overlooked in commit a86af42e22447154398716af35779702d4716c06 Signed-off-by: Ronald Barnes --- complete.occ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/complete.occ b/complete.occ index 60b4c4c17846b..eb2d17c109f87 100644 --- a/complete.occ +++ b/complete.occ @@ -36,7 +36,7 @@ function get_opts_list() ## Verbose settings hard to parse: i.e. "-v|vv|vvv, --verbose" ## Just manually add -vv and -vvv, and place in order (after -v): ## Note: `complete` built-in handles de-duplication and sortation - opts_list[len]="-vv" + opts_list+=("-vv") opts_list+=("-vvv") } From 2751eaa9aced95349662e94372a0b160144178f5 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Fri, 2 Dec 2022 01:03:08 -0800 Subject: [PATCH 10/47] Added more web server user names. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 3510c0b668ced..61b13ae49f202 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -156,7 +156,7 @@ define_colours declare -a httpdUser ## Find the web server user name: -searchHttpdUser "httpd|www-data" +searchHttpdUser "httpd|www-data|nginx|lighthttpd" if [ ${#httpdUser[0]} -eq 0 ] ; then ## No standard httpd user found, try "nobody": searchHttpdUser "nobody" From 8ea5a98cf10ba94366f4598585d75ab93479107e Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 00:47:04 -0800 Subject: [PATCH 11/47] Add user_id to completions. Add apps list to completions. Do not offer a switch as completion if it has already been chosen. Signed-off-by: Ronald Barnes --- complete.occ | 142 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 3 deletions(-) diff --git a/complete.occ b/complete.occ index eb2d17c109f87..ee5da219b123a 100644 --- a/complete.occ +++ b/complete.occ @@ -26,11 +26,29 @@ set colored-stats on ## Get list of options beginning with "-", i.e. --help, --verbose, etc.: function get_opts_list() { + ## Check if passed name of app to run to get app-specific options: + local appName + if [[ $# -gt 0 ]] ; then + appName=${1} + fi + ## Read the \n-delimited list into an array: while read -r value; do - opts_list+=("${value}") + ## Don't display option if already on command line: + ## Use loop; word expansion via [@] does partial matches: + local X foundOpt="no" + for (( X=1 ; X<((${#COMP_WORDS[@]}-1)) ; X++ )) ; do + if [[ ${COMP_WORDS[$X]} == ${value} ]] ; then + foundOpt="yes" + fi + done + ## Don't add CWORD, it can be just "-": + if [[ ${foundOpt} == "no" && ${value} != ${CWORD} ]] ; then + opts_list+=("${value}") + fi + ## Read output of "occ" and get word-chars following "-" or "--": - done <<< $(occ | + done <<< $(occ ${appName} | grep --extended-regex --only-matching " \-(\-|\w)+" ) ## Verbose settings hard to parse: i.e. "-v|vv|vvv, --verbose" @@ -43,6 +61,116 @@ function get_opts_list() + +## Get arguments and options for specific app, i.e. files:scan +function get_apps_args_and_opts() + { + local occCommand getOpts="no" length + if [[ $# -eq 0 ]] ; then + ## Expecting app to run + return 99 + else + occCommand="${@}" + fi + + ## Check if user is asking for opts; normally excluded: + if [[ $CWORD =~ "-" ]] ; then + getOpts="yes" + ## If a command was passed, it cannot END with "--", that means + ## "end of options, next is input" in bash. + ## So, strip "-" or "--" if they're CWORD: + if [[ $CWORD =~ "-"$ ]] ; then + occCommand=${@%%-*} + fi + fi + + local value + local args args_list + local opts opts_list + + ## Get all output into one var: + args=$(occ ${occCommand} --help --raw 2>&1) + ## Save a copy and avoid running occ twice (once for args, once for opts): + opts=args + + if [[ ${args} =~ Arguments: && $getOpts == no ]] ; then + ## Remove to and including Arguments: header: + args=${args#*Arguments:} + ## Remove Options: header to end of list: + args=${args%%Options:*} + ## Found arguments, read them to array: + while read -r value ; do + ## Strip trailing blanks: + value=${value%% *} + ## Skip blank lines: + if [[ ${value} =~ [:punct::alnum:]+ ]] ; then + args_list+=("${value}") + fi + done <<< ${args} + + ## If an arg is "app", get list of all apps, + if [[ ${args_list[@]} =~ "app" ]] ; then + ## Put list of apps into array for completing next input + echo "get_apps_list" + fi + + ## if an arg is "user_id", get list of all users: + if [[ ${args_list[@]} =~ "user_id" ]] ; then + ## Put list of users into array for completing next input + get_users_list + fi + fi + + if [[ $getOpts == yes ]] ; then + get_opts_list "${occCommand} --help" + display_args_arr+=(${opts_list[@]}) + fi + } + + + +## Put list of users into array for completing next input +function get_users_list() + { + local value + while read -r value ; do + ## Strip trailing characters after and including colon: + value=${value%%:*} + ## Strip leading blanks: + value=${value##* } + ## Don't include a user already on the command line: + if [[ ! ${COMP_WORDS[@]} =~ ${value} ]] ; then + display_args_arr+=("${value}") + fi + done <<< $(occ user:list) + } + + + +## Put list of apps into array for completing next input +function get_apps_list() + { + local args value + args=$(occ app:list) + while read -r value ; do + ## Strip trailing characters after and including colon: + value=${value%%:*} + ## Strip leading blanks: + value=${value##* } + ## Skip "Enabled" and "Disabled" section headers: + if [[ ! (${value} == "Enabled" || ${value} == "Disabled") ]] ; then + display_args_arr+=("${value}") + fi + done <<< ${args} + } + + + + + + + + ## This runs the completions for "occ" command, which is an alias to: ## sudo -u $web_server_user php occ function _occ() @@ -94,8 +222,16 @@ function _occ() + ## If ANY PREVIOUS word has colon, it's a command, run it and get its + ## arguments and options: + if [[ ( ${COMP_WORDS[@]:1:((${#COMP_WORDS[@]}-1))} =~ : ) + ## Ensure that above condition does not include current word, + ## which can happen if index 0 == occ and index 1 == files:scan + && (! ${CWORD} =~ : ) ]] ; then + local length=${#COMP_WORDS[@]}-1 + get_apps_args_and_opts "${COMP_WORDS[@]:1:length}" ## Check for hyphen / dash / "-" as first char, if so, get options list: - if [[ ${CWORD:0:1} == - ]] ; then + elif [[ ${CWORD:0:1} == - ]] ; then get_opts_list display_args_arr=${opts_list[@]} From 7825a8f32ce63a572cf0ceb00398d54284129b69 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 00:48:49 -0800 Subject: [PATCH 12/47] Web server lighthttp user name is fixed to lighttpd. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 61b13ae49f202..c1c8b63e955e8 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -156,7 +156,7 @@ define_colours declare -a httpdUser ## Find the web server user name: -searchHttpdUser "httpd|www-data|nginx|lighthttpd" +searchHttpdUser "httpd|www-data|nginx|lighttpd" if [ ${#httpdUser[0]} -eq 0 ] ; then ## No standard httpd user found, try "nobody": searchHttpdUser "nobody" From aed5edd10c0e2124106600446a2404ca4a4ffc23 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 01:29:24 -0800 Subject: [PATCH 13/47] Added Usage: and remove unused debugging. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index c1c8b63e955e8..f3865d36f1ae6 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -11,12 +11,14 @@ ## ## @copyright Copyright © 2022, Ronald Barnes (ron@ronaldbarnes.ca) ## ########################################################################### +## +## Usage: +## . bash-add-alias.sh +## or: +## source bash-add-alias.sh +## ########################################################################### -## Dubugging: -## set -x -## Errors exit immediately: -## set -e ## Catch undefined vars: set -u From c3a84703f42fde8db92f30133c0bdcfbf1b98b88 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 12:55:03 -0800 Subject: [PATCH 14/47] Added user_id, app, lang, and file system completions. Signed-off-by: Ronald Barnes --- complete.occ | 88 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/complete.occ b/complete.occ index ee5da219b123a..ce8423cc487c7 100644 --- a/complete.occ +++ b/complete.occ @@ -17,7 +17,7 @@ ## ~/.inputrc or /etc/inputrc: ## from "man readline": set colored-completion-prefix on -set colored-stats on +## set colored-stats on @@ -111,7 +111,7 @@ function get_apps_args_and_opts() ## If an arg is "app", get list of all apps, if [[ ${args_list[@]} =~ "app" ]] ; then ## Put list of apps into array for completing next input - echo "get_apps_list" + get_apps_list fi ## if an arg is "user_id", get list of all users: @@ -119,6 +119,12 @@ function get_apps_args_and_opts() ## Put list of users into array for completing next input get_users_list fi + + ## if an arg is "lang", get list of all languages FOR CHOSEN APP: + if [[ ${args_list[@]} =~ "lang" ]] ; then + ## Put list of languages into array for completing next input + get_languages_list + fi fi if [[ $getOpts == yes ]] ; then @@ -151,7 +157,10 @@ function get_users_list() function get_apps_list() { local args value - args=$(occ app:list) + ## Only repopulate apps list if not done already in this instance: + if [[ -z ${occ_apps_list} ]] ; then + occ_apps_list=$(occ app:list) + fi while read -r value ; do ## Strip trailing characters after and including colon: value=${value%%:*} @@ -161,10 +170,38 @@ function get_apps_list() if [[ ! (${value} == "Enabled" || ${value} == "Disabled") ]] ; then display_args_arr+=("${value}") fi - done <<< ${args} + done <<< ${occ_apps_list} } +## If an app expects "lang" arg (language), then present completion list of +## file system entries so they can locate xx_YY.php +function get_languages_list() + { + ## NOTE: l18n:createjs expects: + ## app: an app name from app:list + ## lang: a PHP file, which user must provide: + ## PHP translation file + ## does not exist. + ## + ## Nothing can be done until PWORD is an app. + + ## If we have an apps list and the Previous WORD is in it... + if [[ -n ${occ_apps_list} && ${occ_apps_list} =~ ${PWORD} ]] ; then + ## Allow for file system completions: + compgen_skip="yes" +# compopt -o filenames +# compopt -o dirnames + fi + } + + + + + + + + @@ -180,18 +217,14 @@ function _occ() ## Previous Word being inspected (PWORD==Previous WORD): local PWORD=${COMP_WORDS[COMP_CWORD-1]} - ## Change word break chars to exclude ":" and "-", since occ uses them: - COMP_WORDBREAKS_ORIG="${COMP_WORDBREAKS}" - COMP_WORDBREAKS=${COMP_WORDBREAKS/:/} - COMP_WORDBREAKS=${COMP_WORDBREAKS/-/} + ## Change word break chars to exclude ":" since occ uses as separator: + COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}" - ## Default is word list, but "index" requires a file name, let readline - ## handle that, per + ## Default is word list, but files:scan, etc. require file name, + ## allow readline to handle that, per ## 'https://stackoverflow.com/questions/12933362/getting-compgen-to-include-slashes-on-directories-when-looking-for-files/19062943#19062943' compgen_skip="no" compopt +o default - ## Since ":" is valid, and requires further sub-args, add NO SPACEs to end: - compopt +o nospace ## Put the options to present to user into this: declare -a display_args_arr @@ -206,7 +239,9 @@ function _occ() ## temp storage to parse to array: local occ_args - + ## List of apps available is used in multiple locations, + ## populate once, globally: + occ_apps_list="" ## Gather all valid args reported by running "occ": while read -r occ_args ; do @@ -216,29 +251,33 @@ function _occ() occ_args_arr+=("${occ_args}") fi done <<< $(occ --raw 2>&1| - ## Starts with alpha-numerics, can include colons and/or hyphens: - grep --extended-regex --only-matching "^[[:alnum:]:-]+" + ## Starts with alpha-numerics, can include colons, hyphens, _s: + grep --extended-regex --only-matching "^[[:alnum:]:_-]+" ) - + ## If we're expecing a file path, let readline defaults handle it: + if [[ $CWORD == -p || $PWORD =~ "--path" || $CWORD =~ "--path" ]] ; then + compgen_skip="yes" +# compopt -o filenames +# compopt -o dirnames ## If ANY PREVIOUS word has colon, it's a command, run it and get its ## arguments and options: - if [[ ( ${COMP_WORDS[@]:1:((${#COMP_WORDS[@]}-1))} =~ : ) + elif [[ ( ${COMP_WORDS[@]:1:((${#COMP_WORDS[@]}-1))} =~ : ) ## Ensure that above condition does not include current word, ## which can happen if index 0 == occ and index 1 == files:scan - && (! ${CWORD} =~ : ) ]] ; then + ## Also, ensure we don't handle --path= here: + && ! ( ${CWORD} =~ : || ${PWORD} =~ = ) ]] ; then local length=${#COMP_WORDS[@]}-1 get_apps_args_and_opts "${COMP_WORDS[@]:1:length}" ## Check for hyphen / dash / "-" as first char, if so, get options list: elif [[ ${CWORD:0:1} == - ]] ; then get_opts_list display_args_arr=${opts_list[@]} - ## If this is first word (after "occ"), shorten list of valid choices ## by stripping everything after first ":" ## There can easily be 180+ options otherwise! - ## Note: there's always an empty second array element after "occ": + ## Note: there's initially an empty second array element after "occ": ## Test for incomplete word by seeking colons: elif [[ ! ${CWORD} =~ : ]]; then ## Use associative array to get *unique* values: @@ -267,10 +306,11 @@ function _occ() fi - local candidates=$(compgen -W "${display_args_arr[*]}" -- "${CWORD}") + local candidates=$( + compgen -W "${display_args_arr[*]}" -- "${CWORD}" + ) ## When no matches, or an option takes a list of files, support ## readline's default behaviour of completing files/directories: - ## (may not apply to occ options, or ... maybe there is one I haven't seen) if [ ${#candidates[@]} -eq 0 ] || [ "${compgen_skip}" == "yes" ]; then compopt -o default COMPREPLY=() @@ -278,9 +318,7 @@ function _occ() COMPREPLY=($(printf '%s' "${candidates[@]}")) fi - ## Reset word-break chars: - COMP_WORDBREAKS=${COMP_WORDBREAKS_ORIG} - unset COMP_WORDBREAKS_ORIG + unset occ_apps_list } complete -F _occ occ From d9ae83df31957912e067628967e685389c83d736 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 13:38:12 -0800 Subject: [PATCH 15/47] Changed all functions to have '_occ_' prefix. Tidied up 'compopt' settings. Signed-off-by: Ronald Barnes --- complete.occ | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/complete.occ b/complete.occ index ce8423cc487c7..fc064db75a589 100644 --- a/complete.occ +++ b/complete.occ @@ -24,7 +24,7 @@ set colored-completion-prefix on ## Get list of options beginning with "-", i.e. --help, --verbose, etc.: -function get_opts_list() +function _occ_get_opts_list() { ## Check if passed name of app to run to get app-specific options: local appName @@ -63,7 +63,7 @@ function get_opts_list() ## Get arguments and options for specific app, i.e. files:scan -function get_apps_args_and_opts() +function _occ_get_apps_args_and_opts() { local occCommand getOpts="no" length if [[ $# -eq 0 ]] ; then @@ -111,24 +111,24 @@ function get_apps_args_and_opts() ## If an arg is "app", get list of all apps, if [[ ${args_list[@]} =~ "app" ]] ; then ## Put list of apps into array for completing next input - get_apps_list + _occ_get_apps_list fi ## if an arg is "user_id", get list of all users: if [[ ${args_list[@]} =~ "user_id" ]] ; then ## Put list of users into array for completing next input - get_users_list + _occ_get_users_list fi ## if an arg is "lang", get list of all languages FOR CHOSEN APP: if [[ ${args_list[@]} =~ "lang" ]] ; then ## Put list of languages into array for completing next input - get_languages_list + _occ_get_languages_list fi fi if [[ $getOpts == yes ]] ; then - get_opts_list "${occCommand} --help" + _occ_get_opts_list "${occCommand} --help" display_args_arr+=(${opts_list[@]}) fi } @@ -136,7 +136,7 @@ function get_apps_args_and_opts() ## Put list of users into array for completing next input -function get_users_list() +function _occ_get_users_list() { local value while read -r value ; do @@ -154,7 +154,7 @@ function get_users_list() ## Put list of apps into array for completing next input -function get_apps_list() +function _occ_get_apps_list() { local args value ## Only repopulate apps list if not done already in this instance: @@ -176,7 +176,7 @@ function get_apps_list() ## If an app expects "lang" arg (language), then present completion list of ## file system entries so they can locate xx_YY.php -function get_languages_list() +function _occ_get_languages_list() { ## NOTE: l18n:createjs expects: ## app: an app name from app:list @@ -190,8 +190,6 @@ function get_languages_list() if [[ -n ${occ_apps_list} && ${occ_apps_list} =~ ${PWORD} ]] ; then ## Allow for file system completions: compgen_skip="yes" -# compopt -o filenames -# compopt -o dirnames fi } @@ -259,8 +257,6 @@ function _occ() ## If we're expecing a file path, let readline defaults handle it: if [[ $CWORD == -p || $PWORD =~ "--path" || $CWORD =~ "--path" ]] ; then compgen_skip="yes" -# compopt -o filenames -# compopt -o dirnames ## If ANY PREVIOUS word has colon, it's a command, run it and get its ## arguments and options: elif [[ ( ${COMP_WORDS[@]:1:((${#COMP_WORDS[@]}-1))} =~ : ) @@ -269,10 +265,10 @@ function _occ() ## Also, ensure we don't handle --path= here: && ! ( ${CWORD} =~ : || ${PWORD} =~ = ) ]] ; then local length=${#COMP_WORDS[@]}-1 - get_apps_args_and_opts "${COMP_WORDS[@]:1:length}" + _occ_get_apps_args_and_opts "${COMP_WORDS[@]:1:length}" ## Check for hyphen / dash / "-" as first char, if so, get options list: elif [[ ${CWORD:0:1} == - ]] ; then - get_opts_list + _occ_get_opts_list display_args_arr=${opts_list[@]} ## If this is first word (after "occ"), shorten list of valid choices ## by stripping everything after first ":" From 39555907d3cadf823a2ed70a92871cc032b1ff82 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 16:51:52 -0800 Subject: [PATCH 16/47] Specify type of entity being 'unset'. Run 'unset bash_aliases' to remove the function from environment. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index f3865d36f1ae6..6c8b059ccb42d 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -36,27 +36,27 @@ function define_colours() ## Leave no trace after exit (except alias(es)): function cleanup_vars() { - unset value - unset httpdUser - unset user_name - unset home_dir - unset aliasExists - unset phpFound - unset answer - unset aliasString - unset addAlias - unset aliasExists - - unset searchHttpdUser - unset occOwner - unset occPath - unset getOccPath - unset script_found - - unset green - unset yellow - unset red - unset default_colour + unset -v value + unset -v httpdUser + unset -v user_name + unset -v home_dir + unset -v aliasExists + unset -v phpFound + unset -v answer + unset -v aliasString + unset -v addAlias + unset -v aliasExists + + unset -f searchHttpdUser + unset -v occOwner + unset -v occPath + unset -f getOccPath + unset -v script_found + + unset -v green + unset -v yellow + unset -v red + unset -v default_colour ## Reset all trap signals: trap - SIGINT @@ -68,10 +68,11 @@ function cleanup_vars() ## If param was passed, i.e. "ALL", cleanup EVERYTHING, we're done: if [[ ${#@} -ge 1 ]]; then trap - RETURN - unset cleanup_vars + unset -f cleanup_vars ## Reset unbound var checking, else i.e. bash completion breaks, etc. set +u - unset define_colours + unset -f define_colours + unset -f bash_aliases fi } From e8e8e78d2e4f32cdcbd765c91ef83129c57de399 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 18:16:51 -0800 Subject: [PATCH 17/47] Changed ownership test to file config/config.php, not ./occ Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 6c8b059ccb42d..70c675842b460 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -202,11 +202,11 @@ else echo "Can't find \"occ\", not in current directory." getOccPath fi - occOwner=$(stat --format="%U" ${occPath}) + occOwner=$(stat --format="%U" ${occPath%/*}/config/config.php) if [[ ${occOwner} != ${httpdUser[0]} ]] ; then - echo -e "${red}ERROR${default_colour}: Owner of occ is not web server user:" + echo -en "${red}ERROR${default_colour}: Owner of config/config.php " + echo "is not web server user:" echo " ${occOwner} != ${httpdUser}" - ## kill -s SIGKILL $$ kill -s SIGINT $$ trap - RETURN return 99 @@ -219,7 +219,6 @@ else echo "Y" eval alias "${aliasString}" alias occ -## elif [[ ${answer} != "" ]] ; then else echo "N" fi From 7eaeb9d7b3b09d8d40e4819e6a4046eabcc4f38b Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 18:34:39 -0800 Subject: [PATCH 18/47] Added colour to filename when ownership mis-match. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 70c675842b460..6ac35537b627b 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -204,7 +204,8 @@ else fi occOwner=$(stat --format="%U" ${occPath%/*}/config/config.php) if [[ ${occOwner} != ${httpdUser[0]} ]] ; then - echo -en "${red}ERROR${default_colour}: Owner of config/config.php " + echo -en "${red}ERROR${default_colour}: Owner of " + echo -en "${yellow}config/config.php${default_colour} " echo "is not web server user:" echo " ${occOwner} != ${httpdUser}" kill -s SIGINT $$ From 0d650f7eb6c085618f8c6649f18be893c59a69bf Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 21:41:45 -0800 Subject: [PATCH 19/47] If no ~/.bash_aliases, then offer to create /etc/profile.d/occ instead. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 6ac35537b627b..946fcdd3fa359 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -57,6 +57,7 @@ function cleanup_vars() unset -v yellow unset -v red unset -v default_colour + unset -v occ_asked_add_alias ## Reset all trap signals: trap - SIGINT @@ -141,8 +142,25 @@ function bash_aliases() echo "N" fi else - echo -ne "${yellow}NOTICE${default_colour}: Cannot access " - echo -e "${home_dir}/.bash_aliases" + ## No user ~/.bash_aliases found, check system-wide location: + ## But, only if we have not already asked, which can happen + ## if there is a $USER and a $SUDO_USER but neither have ~/.bash_aliases + if [[ (! -r /etc/profile.d/occ) && ($occ_asked_add_alias == no) ]] ; then + ## Ask if user wants an alias added to /etc/profile.d/occ + echo -en "Create alias file ${yellow}/etc/profile.d/occ${default_colour}?" + read -s -p " (y/N) " -n 1 answer + occ_asked_add_alias="yes" + if [[ ${answer} =~ ^Y|y ]] ; then + echo "Y" + echo "${aliasString}" > /etc/profile.d/occ + answer=$? + if [[ ${answer} -eq 0 ]] ; then + ls -l /etc/profile.d/occ + fi + else + echo "N" + fi + fi fi } @@ -155,6 +173,9 @@ trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM ## Handy red / yellow / green / default colour defs: define_colours +## Prevent asking twice if no ~/.bash_aliases nor $SUDO_USER/.bash_aliases +occ_asked_add_alias="no" + ## Store web server user name(s) from /etc/passwd as indexed array: declare -a httpdUser From 6ddaf0f4142b630eefe83bd4fb67d2ae9bf45a5d Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 5 Dec 2022 23:10:28 -0800 Subject: [PATCH 20/47] Offer to add alias to /etc/bash.bashrc as well as ~/.bash_aliases Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 61 +++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 946fcdd3fa359..c635c97ed1da2 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -5,7 +5,9 @@ ## ## Optionally adds the alias to user's .bash_aliases file ## Optionally adds the alias to SUDO_USER's .bash_aliases file -## Verifies `occ` is owned by web server user +## If neither user has ~/.bash_aliases, optionally add to /etc/bash.bashrc +## +## Verifies `config/config.php` is owned by web server user ## Optionally copies bash completion script `complete.occ` to ## /etc/bash_completion.d/ ## @@ -57,7 +59,6 @@ function cleanup_vars() unset -v yellow unset -v red unset -v default_colour - unset -v occ_asked_add_alias ## Reset all trap signals: trap - SIGINT @@ -115,52 +116,36 @@ function getOccPath() function bash_aliases() { - if [[ $# -eq 0 ]] ; then - ## Expecting path to .bash_aliases directory + if [[ $# -ne 2 ]] ; then + ## Expecting path and file, i.e. ~ and .bash_aliases return 99 else - home_dir=${1} + local home_dir=${1} + local alias_file=${2} fi - grep --no-messages "occ" ${home_dir}/.bash_aliases + if [[ ! -r ${1}/${2} ]] ; then + return + fi + grep --quiet --no-messages "occ" ${home_dir}/${alias_file} aliasExists=$? if [[ aliasExists -eq 0 ]]; then - echo "There is an \"occ\" alias in ${home_dir}.bash_aliases:" - grep "occ" ${home_dir}/.bash_aliases - elif [[ -w ${home_dir}/.bash_aliases ]]; then - echo -en "Add alias to ${yellow}${home_dir}/.bash_aliases${default_colour}?" + echo "There is an \"occ\" alias in ${home_dir}/${alias_file}:" + grep "occ" ${home_dir}/${alias_file} + elif [[ -w ${home_dir}/${alias_file} ]]; then + echo -en "Add alias to ${yellow}${home_dir}/${alias_file}${default_colour}?" read -s -p " (y/N) " -n 1 answer if [[ ${answer} =~ ^Y|y ]] ; then echo "Y" - echo "${aliasString}" >> ${home_dir}/.bash_aliases + echo "${aliasString}" >> ${home_dir}/${alias_file} answer=$? if [[ ${answer} -eq 0 ]] ; then echo -ne "${green}Success${default_colour}: " - grep occ ${home_dir}/.bash_aliases + grep occ ${home_dir}/${alias_file} fi else echo "N" fi - else - ## No user ~/.bash_aliases found, check system-wide location: - ## But, only if we have not already asked, which can happen - ## if there is a $USER and a $SUDO_USER but neither have ~/.bash_aliases - if [[ (! -r /etc/profile.d/occ) && ($occ_asked_add_alias == no) ]] ; then - ## Ask if user wants an alias added to /etc/profile.d/occ - echo -en "Create alias file ${yellow}/etc/profile.d/occ${default_colour}?" - read -s -p " (y/N) " -n 1 answer - occ_asked_add_alias="yes" - if [[ ${answer} =~ ^Y|y ]] ; then - echo "Y" - echo "${aliasString}" > /etc/profile.d/occ - answer=$? - if [[ ${answer} -eq 0 ]] ; then - ls -l /etc/profile.d/occ - fi - else - echo "N" - fi - fi fi } @@ -173,9 +158,6 @@ trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM ## Handy red / yellow / green / default colour defs: define_colours -## Prevent asking twice if no ~/.bash_aliases nor $SUDO_USER/.bash_aliases -occ_asked_add_alias="no" - ## Store web server user name(s) from /etc/passwd as indexed array: declare -a httpdUser @@ -247,7 +229,7 @@ else fi ## Is there an occ alias in ~/.bash_aliases? -bash_aliases $HOME +bash_aliases $HOME ".bash_aliases" home_dir="" if [[ "${SUDO_USER}" != "" ]] ; then ## Find user-who-ran-sudo's home directory: @@ -257,10 +239,15 @@ if [[ "${SUDO_USER}" != "" ]] ; then ## Strip off start-of-line->last colon: home_dir=${home_dir##*:} if [[ "$HOME" != "${home_dir}" ]] ; then - bash_aliases ${home_dir} + bash_aliases ${home_dir} .bash_aliases fi fi +## Also offer to add alias to /etc/bash.bashrc since ~/.bash_aliases unlikely +## to exist and user may want this option for global alias: +bash_aliases "/etc" "bash.bashrc" + + ## Run complete.occ to handle bash auto completion? script_found=1 ## aka False From efa1dc358ee2402832a924bf4ae72345f702f3e8 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Tue, 6 Dec 2022 23:44:03 -0800 Subject: [PATCH 21/47] Option to add completion script to ~/.local/share/bash-completion/completions. When copying complete.occ, target file is called 'occ'. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index c635c97ed1da2..80d0c3134715b 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -54,6 +54,7 @@ function cleanup_vars() unset -v occPath unset -f getOccPath unset -v script_found + unset -v script_installed unset -v green unset -v yellow @@ -281,25 +282,32 @@ fi ## Does `complete.occ` exist in /etc/bash_completion.d/? ## Does `complete.occ` exist in /usr/share/bash-completion/completions/? ## If neither, add it to /etc/bash_completion.d/? +script_installed=1 if [[ -d /etc/bash_completion.d ]] ; then if [[ -f /etc/bash_completion.d/complete.occ ]] ; then - script_found=0 + script_installed=0 echo "Found existing complete.occ in /etc/bash_completion.d/" else if [[ -f ${occPath}/complete.occ ]] ; then - echo -en "Add ${yellow}complete.occ${default_colour} " - echo -en "to /etc/bash_completion.d?" + echo -en "Copy ${yellow}complete.occ${default_colour} " + echo -en "to ${yellow}/etc/bash_completion.d/occ${default_colour}?" read -sp " (y/N) " -n 1 answer if [[ ${answer} =~ ^[Yy] ]] ; then echo "Y" - cp -v complete.occ /etc/bash_completion.d + cp --verbose \ + --archive \ + --preserve=all \ + --interactive \ + complete.occ /etc/bash_completion.d/occ if [[ $? -ne 0 ]] ; then echo -ne "${red}ERROR${default_colour}: Could not " echo -e "copy complete.occ to /etc/bash_completion.d/" + script_installed=-1 else + script_installed=0 ## Copy successful, set owner and permissions: - chown -v root:root /etc/bash_completion.d/complete.occ - chmod -v 0644 /etc/bash_completion.d/complete.occ + chown -v root:root /etc/bash_completion.d/occ + chmod -v 0644 /etc/bash_completion.d/occ fi else echo "N" @@ -308,7 +316,30 @@ if [[ -d /etc/bash_completion.d ]] ; then fi fi - +## If /etc/bash_completion.d does not exist, or user declined to copy +## script to that location, offer to copy to local user storage: +if [[ script_installed -ne 0 ]] ; then + echo -en "Copy ${yellow}complete.occ${default_colour} to " + echo -en "${yellow}~/.local/share/bash-completion/completions/occ" + echo -en "${default_colour}?" + read -sp " (y/N) " -n 1 answer + if [[ ${answer} =~ ^[Yy] ]] ; then + echo "Y" + mkdir -vp ~/.local/share/bash-completion/completions + ## File name MUST have name of command / alias it operates on when + ## it is in this location: + cp --verbose \ + --archive \ + --preserve=all \ + --interactive \ + complete.occ ~/.local/share/bash-completion/completions/occ + else + echo "N" + fi +fi + + + ## Cannot remove trap on RETURN inside a return trap catch, so do it here: trap - RETURN From 3fa70e763e79c9de21a866f673a22d75a5beb9eb Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 7 Dec 2022 01:15:36 -0800 Subject: [PATCH 22/47] If no ~/.bash_aliases, offer to append to ~/.bashrc instead of /etc/bash.bashrc Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 80d0c3134715b..c15902e05a900 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -55,6 +55,7 @@ function cleanup_vars() unset -f getOccPath unset -v script_found unset -v script_installed + unset -v alias_installed unset -v green unset -v yellow @@ -133,6 +134,7 @@ function bash_aliases() if [[ aliasExists -eq 0 ]]; then echo "There is an \"occ\" alias in ${home_dir}/${alias_file}:" grep "occ" ${home_dir}/${alias_file} + alias_installed=0 elif [[ -w ${home_dir}/${alias_file} ]]; then echo -en "Add alias to ${yellow}${home_dir}/${alias_file}${default_colour}?" read -s -p " (y/N) " -n 1 answer @@ -143,6 +145,7 @@ function bash_aliases() if [[ ${answer} -eq 0 ]] ; then echo -ne "${green}Success${default_colour}: " grep occ ${home_dir}/${alias_file} + alias_installed=0 fi else echo "N" @@ -230,6 +233,7 @@ else fi ## Is there an occ alias in ~/.bash_aliases? +alias_installed=1 bash_aliases $HOME ".bash_aliases" home_dir="" if [[ "${SUDO_USER}" != "" ]] ; then @@ -244,9 +248,14 @@ if [[ "${SUDO_USER}" != "" ]] ; then fi fi +## If no alias installed into any ~/.bash_aliases file, try ~/.bashrc: +if [[ $alias_installed -ne 0 ]] ; then + ## Try SUDO_USER's home dir, if not defined, use $HOME: + bash_aliases ${home_dir:-HOME} .bashrc +fi ## Also offer to add alias to /etc/bash.bashrc since ~/.bash_aliases unlikely ## to exist and user may want this option for global alias: -bash_aliases "/etc" "bash.bashrc" +## bash_aliases "/etc" "bash.bashrc" From b23f709c77ff1bcb2d9031d89b8f7d0746a258f5 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 7 Dec 2022 01:16:03 -0800 Subject: [PATCH 23/47] Updated documentation / usage. Signed-off-by: Ronald Barnes --- complete.occ | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/complete.occ b/complete.occ index fc064db75a589..b8da171ff7262 100644 --- a/complete.occ +++ b/complete.occ @@ -1,10 +1,16 @@ #!/bin/bash ## ########################################################################### -## Place this file in /etc/bash_completion.d so that -## it can get processed each time a new bash session is run. +## Companion script bash-add-alias.sh will install / invoke this script. ## -## Ensure it is owned by root:root (chown -v root:root thisFileName +## bash-add-alias.sh or the user can copy this file to either +## /etc/bash_completion.d/occ +## or +## ~/.local/share/bash-completion/completions/occ +## so that it can get processed each time a new bash session is run. +## +## If copied to /etc/bash_completion.d/occ, then +## ensure it is owned by root:root (chown -v root:root thisFileName ## Also, only root can edit it: (chmod -v 0644 thisFileName) ## ## You may need to install bash-completion package, i.e.: From b9a4081b6ccbd994e7c41fb25a14f536e80ed2d4 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 7 Dec 2022 03:50:50 -0800 Subject: [PATCH 24/47] Added more web server user names, per https://docs.nextcloud.com/server/22/admin_manual/configuration_server/occ_command.html#http-user-label Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index c15902e05a900..5a67913249d89 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -166,7 +166,9 @@ define_colours declare -a httpdUser ## Find the web server user name: -searchHttpdUser "httpd|www-data|nginx|lighttpd" +## More added per +## https://docs.nextcloud.com/server/22/admin_manual/configuration_server/occ_command.html#http-user-label +searchHttpdUser "httpd|www-data|nginx|lighttpd|apache|http|wwwrun" if [ ${#httpdUser[0]} -eq 0 ] ; then ## No standard httpd user found, try "nobody": searchHttpdUser "nobody" From 161c000b3c44bf3ef94ad867c7f923fc9b955a6d Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 7 Dec 2022 13:00:23 -0800 Subject: [PATCH 25/47] Added @author, reformatted @copyright. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 3 ++- complete.occ | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 5a67913249d89..d81d491cfec6c 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -11,7 +11,8 @@ ## Optionally copies bash completion script `complete.occ` to ## /etc/bash_completion.d/ ## -## @copyright Copyright © 2022, Ronald Barnes (ron@ronaldbarnes.ca) +## @author Ronald Barnes +## @copyright Copyright 2022, Ronald Barnes ron@ronaldbarnes.ca ## ########################################################################### ## ## Usage: diff --git a/complete.occ b/complete.occ index b8da171ff7262..5e4cbb01f430e 100644 --- a/complete.occ +++ b/complete.occ @@ -16,7 +16,8 @@ ## You may need to install bash-completion package, i.e.: ## sudo apt install bash-completion ## -## @copyright Copyright © 2022, Ronald Barnes (ron@ronaldbarnes.ca) +## @author Ronald Barnes +## @copyright Copyright 2022, Ronald Barnes ron@ronaldbarnes.ca ## ########################################################################### ## ## NOTE: for best bash_completion experience, add the following lines to From f720c7235cd63ccbad863f9ca850fbc74cf87a29 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 10 Dec 2022 02:26:58 -0800 Subject: [PATCH 26/47] Refactored: removed all global persistence options, stores alias to ~/.bash_aliases or ~/.bashrc and completion file to ~/.local/share/bash-completion/completions Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 346 +++++++++++++++++++--------------------------- 1 file changed, 139 insertions(+), 207 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index d81d491cfec6c..d450b335330ac 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -1,15 +1,16 @@ #!/bin/bash ## ########################################################################### -## Creates an alias to run `occ` as the appropriate web server user +## Creates an alias to run `occ` as the appropriate user: +## the owner of nextcloud/config/config.php +## or +## a common web server user name found in /etc/passwd ## -## Optionally adds the alias to user's .bash_aliases file -## Optionally adds the alias to SUDO_USER's .bash_aliases file -## If neither user has ~/.bash_aliases, optionally add to /etc/bash.bashrc +## Optionally adds the alias to user's .bash_aliases file, if found +## If not found, optionally add alias to ~/.bashrc ## -## Verifies `config/config.php` is owned by web server user -## Optionally copies bash completion script `complete.occ` to -## /etc/bash_completion.d/ +## Optionally copies bash completion script `_occ.bash` to +## ~/.local/share/bash-completion/completions/ ## ## @author Ronald Barnes ## @copyright Copyright 2022, Ronald Barnes ron@ronaldbarnes.ca @@ -21,13 +22,19 @@ ## source bash-add-alias.sh ## ########################################################################### - +## Save original "catch undefined vars" setting: +_occ_orig_set_u=$- +if [[ $_occ_orig_set_u =~ u ]] ; then + _occ_orig_set_u=0 +else + _occ_orig_set_u=1 +fi ## Catch undefined vars: set -u ## Define colours: -function define_colours() +function _occ_define_colours() { green="\e[1;32m" yellow='\e[1;33m' @@ -40,23 +47,22 @@ function define_colours() function cleanup_vars() { unset -v value - unset -v httpdUser unset -v user_name unset -v home_dir - unset -v aliasExists + unset -v _occ_alias_exists unset -v phpFound unset -v answer - unset -v aliasString - unset -v addAlias - unset -v aliasExists - - unset -f searchHttpdUser - unset -v occOwner - unset -v occPath - unset -f getOccPath + unset -v _occ_alias_string + unset -v _occ_alias_exists + + unset -v _occ_nc_path + unset -f _occ_get_nc_path + unset -v _occ_completion_script unset -v script_found - unset -v script_installed - unset -v alias_installed + unset -v _occ_script_installed + unset -v _occ_alias_installed + unset -v _occ_status + unset -v _occ_sudo_user unset -v green unset -v yellow @@ -74,50 +80,29 @@ function cleanup_vars() if [[ ${#@} -ge 1 ]]; then trap - RETURN unset -f cleanup_vars - ## Reset unbound var checking, else i.e. bash completion breaks, etc. - set +u - unset -f define_colours - unset -f bash_aliases - fi - } - -function searchHttpdUser() - { - if [[ $# -eq 0 ]] ; then - ## Expecting user name to search for - return 99 - else - searchUser=${1} + ## Reset unbound var checking to original state: + if [[ ! _occ_orig_set_u -eq 0 ]] ; then + set +u + fi + unset -v _occ_orig_set_u + unset -f _occ_define_colours + unset -f _occ_bash_aliases fi - - ## Fetch possible httpd users (for sudo -u ...) into array: - ## - ## Params: regex / string of name(s) to search for - while read value; do - ## Normal, indexed array: - httpdUser+=($value) - done <<< $(grep \ - --extended-regex \ - --ignore-case \ - --only-matching \ - --max-count=1 \ - "${searchUser}" /etc/passwd \ - ) } -function getOccPath() +function _occ_get_nc_path() { - read -ep "Path to file 'occ': " -i "/" occPath - if [[ ! -f ${occPath} ]] ; then - getOccPath + read -ep "Path to NextCloud directory? " -i "/" _occ_nc_path + if [[ ! -f ${_occ_nc_path}/occ ]] ; then + _occ_get_nc_path fi } -function bash_aliases() +function _occ_bash_aliases() { if [[ $# -ne 2 ]] ; then ## Expecting path and file, i.e. ~ and .bash_aliases @@ -127,26 +112,30 @@ function bash_aliases() local alias_file=${2} fi - if [[ ! -r ${1}/${2} ]] ; then + if [[ ! -w ${home_dir}/${alias_file} ]] ; then return fi grep --quiet --no-messages "occ" ${home_dir}/${alias_file} - aliasExists=$? - if [[ aliasExists -eq 0 ]]; then + _occ_alias_exists=$? + if [[ _occ_alias_exists -eq 0 ]]; then echo "There is an \"occ\" alias in ${home_dir}/${alias_file}:" - grep "occ" ${home_dir}/${alias_file} - alias_installed=0 + echo -n " --> " + grep --color=auto "occ" ${home_dir}/${alias_file} + _occ_alias_installed=0 elif [[ -w ${home_dir}/${alias_file} ]]; then - echo -en "Add alias to ${yellow}${home_dir}/${alias_file}${default_colour}?" + echo -en "Add alias to " + echo -en "${yellow}${home_dir}/${alias_file}${default_colour}?" read -s -p " (y/N) " -n 1 answer if [[ ${answer} =~ ^Y|y ]] ; then echo "Y" - echo "${aliasString}" >> ${home_dir}/${alias_file} + echo "" >> ${home_dir}/${alias_file} + echo "## tab completion for NextCloud:" >> ${home_dir}/${alias_file} + echo "alias occ=${_occ_alias_string}" >> ${home_dir}/${alias_file} answer=$? if [[ ${answer} -eq 0 ]] ; then echo -ne "${green}Success${default_colour}: " - grep occ ${home_dir}/${alias_file} - alias_installed=0 + grep --color=auto occ ${home_dir}/${alias_file} + _occ_alias_installed=0 fi else echo "N" @@ -156,203 +145,146 @@ function bash_aliases() - +## Capture exit conditions to clean up all variables: trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM ## Handy red / yellow / green / default colour defs: -define_colours - -## Store web server user name(s) from /etc/passwd as indexed array: -declare -a httpdUser - -## Find the web server user name: -## More added per -## https://docs.nextcloud.com/server/22/admin_manual/configuration_server/occ_command.html#http-user-label -searchHttpdUser "httpd|www-data|nginx|lighttpd|apache|http|wwwrun" -if [ ${#httpdUser[0]} -eq 0 ] ; then - ## No standard httpd user found, try "nobody": - searchHttpdUser "nobody" +_occ_define_colours + +user_name=$(whoami) +_occ_completion_script="complete.occ" + +## Find NextCloud installation directory +_occ_nc_path=$(pwd) +if [[ ! -f ${_occ_nc_path}/occ ]] ; then + echo -e "Can't find ${yellow}occ${default_colour} in current directory." + _occ_get_nc_path + ## Strip trailing "/" from path: + _occ_nc_path=${_occ_nc_path%/} fi -if [ ${#httpdUser[0]} -eq 0 ] ; then - echo -e "${red}ERROR${default_colour}: No web server user found." - ## kill -s SIGINT $$ - return 1 +## Find owner of config/config.php, should be the web server user, per: +## https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#http-user-label +## but in shared hosting, might not be(?) +_occ_sudo_user="" +if [[ -f ${_occ_nc_path}/config/config.php ]] ; then + _occ_sudo_user=$(stat --format="%U" ${_occ_nc_path}/config/config.php) else - echo -ne "Web server user name: " - echo -e "\"${green}${httpdUser[0]}${default_colour}\"." + echo -en "${red}WARNING${default_colour}: " + echo -en "Cannot locate ${yellow}${_occ_nc_path}/config/config.php" + echo -e "${default_colour}" + ## return 100 + read _occ_sudo_user <<< $(grep --only-matching --extended-regex \ + "www-data|httpd|nginx|lighttpd|apache|http|wwwrun" \ + /etc/passwd + ) fi - +_occ_alias_string="" ## Looks for existing occ alias: -occPath="" -alias occ 2>/dev/null -aliasExists=$? -## USER=root, HOME=/root, SUDO_USER=me: -## user_name=${SUDO_USER:-$USER} -user_name=${USER:-$SUDO_USER} -if [ ${aliasExists} -eq 0 ] ; then - echo "Alias for occ found for user \"${user_name}\"." - aliasString=$(alias occ) - occPath=${aliasString##* } +_occ_alias_string=$(alias occ 2>/dev/null) +_occ_alias_exists=$? +if [ ${_occ_alias_exists} -eq 0 ] ; then + echo "occ alias found for user \"${user_name}\":" + echo -e " --> ${green}$(alias occ)${default_colour}" else - echo "Alias for occ command not found for user \"${user_name}\"." - which php 2>&1 > /dev/null + echo "No occ alias found for user \"${user_name}\"." + ## Note: `which` command not always installed, see if `php` exists this way: + php --version 1>/dev/null 2>/dev/null phpFound=$? if [ $phpFound -ne 0 ]; then echo -e "${red}ERROR${default_colour}: php not found in path." - kill -s SIGKILL $$ - fi - occPath="$(pwd)/occ" - if [[ -f ${occPath} ]] ; then - occPath=$(pwd)/occ - else - echo "Can't find \"occ\", not in current directory." - getOccPath - fi - occOwner=$(stat --format="%U" ${occPath%/*}/config/config.php) - if [[ ${occOwner} != ${httpdUser[0]} ]] ; then - echo -en "${red}ERROR${default_colour}: Owner of " - echo -en "${yellow}config/config.php${default_colour} " - echo "is not web server user:" - echo " ${occOwner} != ${httpdUser}" - kill -s SIGINT $$ - trap - RETURN return 99 fi - - aliasString="occ='sudo --user ${httpdUser} php ${occPath}'" - echo -ne "Run \"${yellow}alias ${green}${aliasString}${default_colour}\"" - read -s -p " (y/N)? " -n 1 answer - if [[ ${answer} =~ ^[Yy] ]] ; then + _occ_alias_string="'sudo --user ${_occ_sudo_user} php ${_occ_nc_path}/occ'" + echo -ne "Run \"${yellow}alias occ=" + echo -ne "${green}${_occ_alias_string}${default_colour}\"" + read -s -p " (Y/n)? " -n 1 answer + if [[ ${answer} =~ ^[Nn] ]] ; then + echo "N" + else echo "Y" - eval alias "${aliasString}" + eval alias "occ=${_occ_alias_string}" alias occ - else - echo "N" fi fi + +_occ_alias_installed=1 ## Is there an occ alias in ~/.bash_aliases? -alias_installed=1 -bash_aliases $HOME ".bash_aliases" -home_dir="" -if [[ "${SUDO_USER}" != "" ]] ; then - ## Find user-who-ran-sudo's home directory: - home_dir=$(grep ${SUDO_USER} /etc/passwd) - ## Strip off colon->end-of-line - home_dir=${home_dir%:*} - ## Strip off start-of-line->last colon: - home_dir=${home_dir##*:} - if [[ "$HOME" != "${home_dir}" ]] ; then - bash_aliases ${home_dir} .bash_aliases - fi -fi +_occ_bash_aliases ${HOME} ".bash_aliases" -## If no alias installed into any ~/.bash_aliases file, try ~/.bashrc: -if [[ $alias_installed -ne 0 ]] ; then - ## Try SUDO_USER's home dir, if not defined, use $HOME: - bash_aliases ${home_dir:-HOME} .bashrc +## If no alias installed into ~/bash_aliases file, try ~/.bashrc: +if [[ $_occ_alias_installed -ne 0 ]] ; then + _occ_bash_aliases ${HOME} ".bashrc" fi -## Also offer to add alias to /etc/bash.bashrc since ~/.bash_aliases unlikely -## to exist and user may want this option for global alias: -## bash_aliases "/etc" "bash.bashrc" - -## Run complete.occ to handle bash auto completion? +## Run ${_occ_completion_script} to handle bash auto completion? script_found=1 ## aka False -## Strip "occ" from occPath: -occPath=${occPath%/*} -if [[ -f ${occPath}/complete.occ ]] ; then +if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then script_found=0 echo -en "Run bash completion script " - echo -en "${green}complete.occ${default_colour}? " + echo -en "${green}${_occ_completion_script}${default_colour}? " read -sp " (Y/n) " -N 1 answer if [[ ${answer} =~ ^[Nn] ]] ; then echo "N" else echo "Y" - echo -n "Running ${occPath}/complete.occ ... " - ## Do not run cleanup_vars() when complete.occ returns: + echo -n "Running ${_occ_nc_path}/${_occ_completion_script} ... " + ## Do not run cleanup_vars() when ${_occ_completion_script} returns: trap - RETURN - source ${occPath}/complete.occ + source ${_occ_nc_path}/${_occ_completion_script} + _occ_status=$? ## Reset trap: trap 'cleanup_vars ALL' RETURN - status=$? - if [[ ${status} -eq 0 ]] ; then + if [[ ${_occ_status} -eq 0 ]] ; then echo -e "${green}success${default_colour}." else echo -e "${red}Error${default_colour}." fi fi +else + echo -en "${red}WARNING${default_colour}: " + echo -en "Cannot find ${yellow}${_occ_nc_path}/${_occ_completion_script}" + echo -e "${default_colour}" fi -## Does `complete.occ` exist in /etc/bash_completion.d/? -## Does `complete.occ` exist in /usr/share/bash-completion/completions/? -## If neither, add it to /etc/bash_completion.d/? -script_installed=1 -if [[ -d /etc/bash_completion.d ]] ; then - if [[ -f /etc/bash_completion.d/complete.occ ]] ; then - script_installed=0 - echo "Found existing complete.occ in /etc/bash_completion.d/" - else - if [[ -f ${occPath}/complete.occ ]] ; then - echo -en "Copy ${yellow}complete.occ${default_colour} " - echo -en "to ${yellow}/etc/bash_completion.d/occ${default_colour}?" - read -sp " (y/N) " -n 1 answer - if [[ ${answer} =~ ^[Yy] ]] ; then - echo "Y" - cp --verbose \ - --archive \ - --preserve=all \ - --interactive \ - complete.occ /etc/bash_completion.d/occ - if [[ $? -ne 0 ]] ; then - echo -ne "${red}ERROR${default_colour}: Could not " - echo -e "copy complete.occ to /etc/bash_completion.d/" - script_installed=-1 - else - script_installed=0 - ## Copy successful, set owner and permissions: - chown -v root:root /etc/bash_completion.d/occ - chmod -v 0644 /etc/bash_completion.d/occ - fi - else - echo "N" - fi - fi - fi -fi -## If /etc/bash_completion.d does not exist, or user declined to copy -## script to that location, offer to copy to local user storage: -if [[ script_installed -ne 0 ]] ; then - echo -en "Copy ${yellow}complete.occ${default_colour} to " - echo -en "${yellow}~/.local/share/bash-completion/completions/occ" - echo -en "${default_colour}?" - read -sp " (y/N) " -n 1 answer - if [[ ${answer} =~ ^[Yy] ]] ; then - echo "Y" - mkdir -vp ~/.local/share/bash-completion/completions - ## File name MUST have name of command / alias it operates on when - ## it is in this location: - cp --verbose \ - --archive \ - --preserve=all \ - --interactive \ - complete.occ ~/.local/share/bash-completion/completions/occ +## Does ${_occ_completion_script} exist in... +## ~/.local/share/bash-completion/completions/? +_occ_script_installed=1 +if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then + if [[ -r ~/.local/share/bash-completion/completions/${_occ_completion_script} ]] ; then + echo -en "Found ${yellow}~/.local/share/bash-completion/completions/" + echo -e "${_occ_completion_script}${default_colour}." else - echo "N" + echo -en "Copy ${yellow}${_occ_completion_script}${default_colour} to " + echo -en "${yellow}~/.local/share/bash-completion/completions/" + echo -en "${default_colour}?" + read -sp " (y/N) " -n 1 answer + if [[ ${answer} =~ ^[Yy] ]] ; then + echo "Y" + mkdir -vp ~/.local/share/bash-completion/completions + ## File name MUST have name of command / alias it operates on when + ## it is in this location, i.e. occ, _occ, or occ.bash: + cp --verbose \ + --archive \ + --preserve=all \ + --interactive \ + ${_occ_nc_path}/${_occ_completion_script} \ + ~/.local/share/bash-completion/completions/ + else + echo "N" + fi fi fi - ## Cannot remove trap on RETURN inside a return trap catch, so do it here: trap - RETURN ## Now clean all vars and remove all traps From f6bbefa9a6a6d255b335e71d7d7a69a07428b2b9 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 10 Dec 2022 04:26:54 -0800 Subject: [PATCH 27/47] Changed completion script destination directory to /etc/bash_completion.d/ Renamed completion script occ.bash Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index d450b335330ac..4650fa0403553 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -10,7 +10,7 @@ ## If not found, optionally add alias to ~/.bashrc ## ## Optionally copies bash completion script `_occ.bash` to -## ~/.local/share/bash-completion/completions/ +## /etc/bash_completion.d/ ## ## @author Ronald Barnes ## @copyright Copyright 2022, Ronald Barnes ron@ronaldbarnes.ca @@ -153,7 +153,7 @@ trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM _occ_define_colours user_name=$(whoami) -_occ_completion_script="complete.occ" +_occ_completion_script="occ.bash" ## Find NextCloud installation directory _occ_nc_path=$(pwd) @@ -166,7 +166,7 @@ fi ## Find owner of config/config.php, should be the web server user, per: -## https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#http-user-label +## https:/docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#http-user-label ## but in shared hosting, might not be(?) _occ_sudo_user="" if [[ -f ${_occ_nc_path}/config/config.php ]] ; then @@ -255,20 +255,20 @@ fi ## Does ${_occ_completion_script} exist in... -## ~/.local/share/bash-completion/completions/? +## /etc/bash_completion.d/? _occ_script_installed=1 if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then - if [[ -r ~/.local/share/bash-completion/completions/${_occ_completion_script} ]] ; then - echo -en "Found ${yellow}~/.local/share/bash-completion/completions/" + if [[ -r /etc/bash_completion.d/${_occ_completion_script} ]] ; then + echo -en "Found ${yellow}/etc/bash_completion.d/" echo -e "${_occ_completion_script}${default_colour}." else echo -en "Copy ${yellow}${_occ_completion_script}${default_colour} to " - echo -en "${yellow}~/.local/share/bash-completion/completions/" + echo -en "${yellow}/etc/bash_completion.d/" echo -en "${default_colour}?" read -sp " (y/N) " -n 1 answer if [[ ${answer} =~ ^[Yy] ]] ; then echo "Y" - mkdir -vp ~/.local/share/bash-completion/completions + mkdir -vp /etc/bash_completion.d ## File name MUST have name of command / alias it operates on when ## it is in this location, i.e. occ, _occ, or occ.bash: cp --verbose \ @@ -276,7 +276,7 @@ if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then --preserve=all \ --interactive \ ${_occ_nc_path}/${_occ_completion_script} \ - ~/.local/share/bash-completion/completions/ + /etc/bash_completion.d/ else echo "N" fi From a3c98c0a66106703b1670b8f5775fbd2b6cf6e62 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 10 Dec 2022 04:29:24 -0800 Subject: [PATCH 28/47] Renamed complete.occ to occ.bash Signed-off-by: Ronald Barnes --- complete.occ => occ.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename complete.occ => occ.bash (98%) diff --git a/complete.occ b/occ.bash similarity index 98% rename from complete.occ rename to occ.bash index 5e4cbb01f430e..87ad17d3044d5 100644 --- a/complete.occ +++ b/occ.bash @@ -4,12 +4,12 @@ ## Companion script bash-add-alias.sh will install / invoke this script. ## ## bash-add-alias.sh or the user can copy this file to either -## /etc/bash_completion.d/occ +## /etc/bash_completion.d/ ## or -## ~/.local/share/bash-completion/completions/occ +## ~/.local/share/bash-completion/completions/ ## so that it can get processed each time a new bash session is run. ## -## If copied to /etc/bash_completion.d/occ, then +## If copied to /etc/bash_completion.d/, then ## ensure it is owned by root:root (chown -v root:root thisFileName ## Also, only root can edit it: (chmod -v 0644 thisFileName) ## From 23fb52497ac633a1e8b9627223a21ab98efa5afc Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 10 Dec 2022 16:38:35 -0800 Subject: [PATCH 29/47] Typo in usage section. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 4650fa0403553..6d5d69005a135 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -9,7 +9,7 @@ ## Optionally adds the alias to user's .bash_aliases file, if found ## If not found, optionally add alias to ~/.bashrc ## -## Optionally copies bash completion script `_occ.bash` to +## Optionally copies bash completion script `occ.bash` to ## /etc/bash_completion.d/ ## ## @author Ronald Barnes From c78dc3c7021fddc67d08ae13a32c169fd338b561 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 10 Dec 2022 22:41:38 -0800 Subject: [PATCH 30/47] Restored chown and chmod on /etc/bash_completion.d/occ.bash Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 6d5d69005a135..c9df7746fd39d 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -277,6 +277,11 @@ if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then --interactive \ ${_occ_nc_path}/${_occ_completion_script} \ /etc/bash_completion.d/ + ## If copy worked, chown and chmod for safety: + if [[ $? -eq 0 ]] ; then + chown -v root:root /etc/bash_completion.d/occ.bash + chmod 0644 /etc/bash_completion.d/occ.bash + fi else echo "N" fi From 0faf097cec0503a047e83ee2ab978b1bd1ccc0f0 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sun, 11 Dec 2022 10:33:51 -0800 Subject: [PATCH 31/47] NextCloud to Nextcloud, camel case to snake case: phpFound to php_found Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index c9df7746fd39d..18fed783689e0 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -50,7 +50,7 @@ function cleanup_vars() unset -v user_name unset -v home_dir unset -v _occ_alias_exists - unset -v phpFound + unset -v php_found unset -v answer unset -v _occ_alias_string unset -v _occ_alias_exists @@ -95,7 +95,7 @@ function cleanup_vars() function _occ_get_nc_path() { - read -ep "Path to NextCloud directory? " -i "/" _occ_nc_path + read -ep "Path to Nextcloud directory? " -i "/" _occ_nc_path if [[ ! -f ${_occ_nc_path}/occ ]] ; then _occ_get_nc_path fi @@ -129,7 +129,7 @@ function _occ_bash_aliases() if [[ ${answer} =~ ^Y|y ]] ; then echo "Y" echo "" >> ${home_dir}/${alias_file} - echo "## tab completion for NextCloud:" >> ${home_dir}/${alias_file} + echo "## tab completion for Nextcloud:" >> ${home_dir}/${alias_file} echo "alias occ=${_occ_alias_string}" >> ${home_dir}/${alias_file} answer=$? if [[ ${answer} -eq 0 ]] ; then @@ -155,7 +155,7 @@ _occ_define_colours user_name=$(whoami) _occ_completion_script="occ.bash" -## Find NextCloud installation directory +## Find Nextcloud installation directory _occ_nc_path=$(pwd) if [[ ! -f ${_occ_nc_path}/occ ]] ; then echo -e "Can't find ${yellow}occ${default_colour} in current directory." @@ -193,8 +193,8 @@ else echo "No occ alias found for user \"${user_name}\"." ## Note: `which` command not always installed, see if `php` exists this way: php --version 1>/dev/null 2>/dev/null - phpFound=$? - if [ $phpFound -ne 0 ]; then + php_found=$? + if [ $php_found -ne 0 ]; then echo -e "${red}ERROR${default_colour}: php not found in path." return 99 fi From 7eb851a8781d4d703955377977f01aba620471eb Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 12 Dec 2022 17:36:35 -0800 Subject: [PATCH 32/47] Switched back to ~/.local/share/bash-completion/completions/ as the target for occ.bash completion script. This will 'lazy load' the file once user first tries to use it. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 18fed783689e0..9f150252c34be 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -10,7 +10,7 @@ ## If not found, optionally add alias to ~/.bashrc ## ## Optionally copies bash completion script `occ.bash` to -## /etc/bash_completion.d/ +## ~/.local/share/bash-completion/completions/ ## ## @author Ronald Barnes ## @copyright Copyright 2022, Ronald Barnes ron@ronaldbarnes.ca @@ -255,15 +255,15 @@ fi ## Does ${_occ_completion_script} exist in... -## /etc/bash_completion.d/? +## ~/.local/share/bash-completion/completions/? _occ_script_installed=1 if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then - if [[ -r /etc/bash_completion.d/${_occ_completion_script} ]] ; then - echo -en "Found ${yellow}/etc/bash_completion.d/" + if [[ -r ~/.local/share/bash-completion/completions/${_occ_completion_script} ]] ; then + echo -en "Found ${yellow}~/.local/share/bash-completion/completions/" echo -e "${_occ_completion_script}${default_colour}." else echo -en "Copy ${yellow}${_occ_completion_script}${default_colour} to " - echo -en "${yellow}/etc/bash_completion.d/" + echo -en "${yellow}~/.local/share/bash-completion/completions/" echo -en "${default_colour}?" read -sp " (y/N) " -n 1 answer if [[ ${answer} =~ ^[Yy] ]] ; then @@ -276,11 +276,11 @@ if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then --preserve=all \ --interactive \ ${_occ_nc_path}/${_occ_completion_script} \ - /etc/bash_completion.d/ + ~/.local/share/bash-completion/completions/ ## If copy worked, chown and chmod for safety: if [[ $? -eq 0 ]] ; then - chown -v root:root /etc/bash_completion.d/occ.bash - chmod 0644 /etc/bash_completion.d/occ.bash + chown -v root:root ~/.local/share/bash-completion/completions/occ.bash + chmod 0644 ~/.local/share/bash-completion/completions/occ.bash fi else echo "N" From 191e1d94faeddfe210367da383571d5aaa17cba4 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 12 Dec 2022 17:58:04 -0800 Subject: [PATCH 33/47] Cleaned up TRAPs; works better with 'read' aka 'readline'. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 9f150252c34be..ae96907a1f245 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -76,18 +76,19 @@ function cleanup_vars() trap - SIGKILL trap - EXIT trap - QUIT - ## If param was passed, i.e. "ALL", cleanup EVERYTHING, we're done: - if [[ ${#@} -ge 1 ]]; then - trap - RETURN - unset -f cleanup_vars - ## Reset unbound var checking to original state: - if [[ ! _occ_orig_set_u -eq 0 ]] ; then - set +u - fi - unset -v _occ_orig_set_u - unset -f _occ_define_colours - unset -f _occ_bash_aliases + unset -f cleanup_vars + ## Reset unbound var checking to original state: + if [[ ! _occ_orig_set_u -eq 0 ]] ; then + set +u fi + unset -v _occ_orig_set_u + unset -f _occ_define_colours + unset -f _occ_bash_aliases + + ## End this program: + kill -s SIGINT $$ + ## End this program, second time if CTRL+C pressed in `read` / `readline`: + kill -s SIGINT $$ } @@ -146,7 +147,7 @@ function _occ_bash_aliases() ## Capture exit conditions to clean up all variables: -trap 'cleanup_vars ALL' RETURN EXIT QUIT SIGINT SIGKILL SIGTERM +trap 'cleanup_vars ALL' EXIT QUIT SIGINT SIGKILL SIGTERM ## Handy red / yellow / green / default colour defs: @@ -234,12 +235,8 @@ if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then else echo "Y" echo -n "Running ${_occ_nc_path}/${_occ_completion_script} ... " - ## Do not run cleanup_vars() when ${_occ_completion_script} returns: - trap - RETURN source ${_occ_nc_path}/${_occ_completion_script} _occ_status=$? - ## Reset trap: - trap 'cleanup_vars ALL' RETURN if [[ ${_occ_status} -eq 0 ]] ; then echo -e "${green}success${default_colour}." else @@ -290,9 +287,6 @@ fi -## Cannot remove trap on RETURN inside a return trap catch, so do it here: -trap - RETURN ## Now clean all vars and remove all traps cleanup_vars ALL -trap -p RETURN echo "DONE." From 4b302d19481c81dca2d3111fd15b4f99cce4712b Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Tue, 13 Dec 2022 01:31:51 -0800 Subject: [PATCH 34/47] Added support for 'occ config:...': handles 'app' and 'system', 'get' and 'set'. If an accepted argument is 'file', handles that as well as 'app', 'user_id', and 'lang'. Signed-off-by: Ronald Barnes --- occ.bash | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/occ.bash b/occ.bash index 87ad17d3044d5..135f6a986cccf 100644 --- a/occ.bash +++ b/occ.bash @@ -127,6 +127,17 @@ function _occ_get_apps_args_and_opts() _occ_get_users_list fi + ## if an arg is "name", get list of all config setting names: + if [[ ${args_list[@]} =~ "name" ]] ; then + ## Put list of users into array for completing next input + _occ_get_setting_names + fi + + ## if an arg is "file", let `readline` defaults handle it: + if [[ ${args_list[@]} =~ "file" ]] ; then + compgen_skip="yes" + fi + ## if an arg is "lang", get list of all languages FOR CHOSEN APP: if [[ ${args_list[@]} =~ "lang" ]] ; then ## Put list of languages into array for completing next input @@ -168,19 +179,88 @@ function _occ_get_apps_list() if [[ -z ${occ_apps_list} ]] ; then occ_apps_list=$(occ app:list) fi + ## If Previous WORD was an app name, don't reload apps as completion options: + if [[ ! ${occ_apps_list[@]} =~ $PWORD ]] ; then + while read -r value ; do + ## Strip trailing characters after and including colon: + value=${value%%:*} + ## Strip leading blanks: + value=${value##* } + ## Skip "Enabled" and "Disabled" section headers: + if [[ ! (${value} == "Enabled" || ${value} == "Disabled") ]] ; then + display_args_arr+=("${value}") + fi + done <<< ${occ_apps_list} + fi + } + + + +## Put list of setting names into array for completing next input +function _occ_get_setting_names() + { + local value skip_until_app="yes" app_name=${PWORD} space_count=4 + + ## If last word is "--value", just return: no competion options to give: + if [[ ${PWORD} == --value ]] ; then + display_args_arr=() + return + fi + + ## Do not expect app name if, i.e. "config.system" has been typed: + if [[ ${PWORD} =~ "config:system" ]] ; then + skip_until_app="no" + app_name="system" + fi + + ## If occ config:system:set is 3 words ago (and Current WORD is blank), + ## only valid option is --value=: + ## i.e. occ config:system:set mail_domain [tab][tab] + ## length-3 length-2 length-1 + ## + local pword3=${#COMP_WORDS[@]} + pword3=$((pword3-3)) + ## + if [[ ( ${COMP_WORDS[$pword3]} == "config:system:set" + || ${COMP_WORDS[$((pword3-1))]} == "config:app:set" ) + && $CWORD == "" ]] ; then + display_args_arr=("--value") + return + + ## If occ config:app:get, then sub-options are 6 spaces from beginning: + elif [[ ${COMP_WORDS[$pword3]} == config:app:get ]] ; then + space_count=6 + skip_until_app="no" + + ## If occ config:app:set, then sub-options are 6 spaces from beginning: + elif [[ ${COMP_WORDS[$pword3]} == config:app:set ]] ; then + space_count=4, + skip_until_app="yes" + space_count=6 + skip_until_app="no" + fi + while read -r value ; do ## Strip trailing characters after and including colon: value=${value%%:*} ## Strip leading blanks: value=${value##* } - ## Skip "Enabled" and "Disabled" section headers: - if [[ ! (${value} == "Enabled" || ${value} == "Disabled") ]] ; then + ## Check if we've reached section header for app named $PWORD + if [[ ${value} == ${PWORD} ]] ; then + skip_until_app="no" + ## Skip until we've reached section header for app named $PWORD: + ## OR, a preceding app isn't necessary if config:system is in effect: + elif [[ ${skip_until_app} == "no" ]] ; then display_args_arr+=("${value}") fi - done <<< ${occ_apps_list} + done <<< $(occ config:list ${app_name} --output plain | + grep --extended-regex --only-matching "^ {$space_count}- [[:alnum:]_.-]+" + ) } + + ## If an app expects "lang" arg (language), then present completion list of ## file system entries so they can locate xx_YY.php function _occ_get_languages_list() @@ -230,6 +310,9 @@ function _occ() ## 'https://stackoverflow.com/questions/12933362/getting-compgen-to-include-slashes-on-directories-when-looking-for-files/19062943#19062943' compgen_skip="no" compopt +o default + ## Put spaces after completed words: + compopt +o nospace + ## Put the options to present to user into this: declare -a display_args_arr From 653ded69000ca66e371f45fc9259283d6e0c4ad4 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sun, 25 Dec 2022 11:48:41 -0800 Subject: [PATCH 35/47] Option to regenerate alias if existing one found (helpful if multiple Nextcloud instances installed). Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 54 +++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index ae96907a1f245..35650e49e3e41 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -63,6 +63,7 @@ function cleanup_vars() unset -v _occ_alias_installed unset -v _occ_status unset -v _occ_sudo_user + unset -f _occ_create_alias unset -v green unset -v yellow @@ -146,6 +147,31 @@ function _occ_bash_aliases() +function _occ_create_alias() + { + ## Note: `which` command not always installed, see if `php` exists this way: + php --version 1>/dev/null 2>/dev/null + php_found=$? + if [ $php_found -ne 0 ]; then + echo -e "${red}ERROR${default_colour}: php not found in path." + return 99 + fi + _occ_alias_string="'sudo --user ${_occ_sudo_user} php ${_occ_nc_path}/occ'" + echo -ne "Run \"${yellow}alias occ=" + echo -ne "${green}${_occ_alias_string}${default_colour}\"" + read -s -p " (Y/n)? " -n 1 answer + if [[ ${answer} =~ ^[Nn] ]] ; then + echo "N" + else + echo "Y" + eval alias "occ=${_occ_alias_string}" + alias occ + fi + } + + + + ## Capture exit conditions to clean up all variables: trap 'cleanup_vars ALL' EXIT QUIT SIGINT SIGKILL SIGTERM @@ -190,26 +216,18 @@ _occ_alias_exists=$? if [ ${_occ_alias_exists} -eq 0 ] ; then echo "occ alias found for user \"${user_name}\":" echo -e " --> ${green}$(alias occ)${default_colour}" -else - echo "No occ alias found for user \"${user_name}\"." - ## Note: `which` command not always installed, see if `php` exists this way: - php --version 1>/dev/null 2>/dev/null - php_found=$? - if [ $php_found -ne 0 ]; then - echo -e "${red}ERROR${default_colour}: php not found in path." - return 99 - fi - _occ_alias_string="'sudo --user ${_occ_sudo_user} php ${_occ_nc_path}/occ'" - echo -ne "Run \"${yellow}alias occ=" - echo -ne "${green}${_occ_alias_string}${default_colour}\"" - read -s -p " (Y/n)? " -n 1 answer - if [[ ${answer} =~ ^[Nn] ]] ; then - echo "N" - else + echo -en "Generate new alias? " + read -sp "(y/N) " -N 1 answer + if [[ ${answer} =~ ^[Yy] ]] ; then echo "Y" - eval alias "occ=${_occ_alias_string}" - alias occ + unalias occ + _occ_create_alias + else + echo "N" fi +else + echo "No occ alias found for user \"${user_name}\"." + _occ_create_alias fi From cfb1720bf973a394d56ce2c7a55cd3e826c23ac6 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 26 Dec 2022 23:24:16 -0800 Subject: [PATCH 36/47] Consistent use of double vs single quotes. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 35650e49e3e41..4fc9f1dad8ecf 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -37,8 +37,8 @@ set -u function _occ_define_colours() { green="\e[1;32m" - yellow='\e[1;33m' - red='\e[1;31m' + yellow="\e[1;33m" + red="\e[1;31m" default_colour="\e[00m" } From 525f7378a13a103601784a38748197a8d6f20d66 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 4 Jan 2023 00:07:27 -0800 Subject: [PATCH 37/47] Changed target for occ.bash to user's ~/.local/share/bash-completion/completions from /etc/bash_completion.d/ -- overlooked it earlier. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash-add-alias.sh b/bash-add-alias.sh index 4fc9f1dad8ecf..6caaa2bef234c 100755 --- a/bash-add-alias.sh +++ b/bash-add-alias.sh @@ -283,7 +283,7 @@ if [[ -f ${_occ_nc_path}/${_occ_completion_script} ]] ; then read -sp " (y/N) " -n 1 answer if [[ ${answer} =~ ^[Yy] ]] ; then echo "Y" - mkdir -vp /etc/bash_completion.d + mkdir -vp ~/.local/share/bash-completion/completions/ ## File name MUST have name of command / alias it operates on when ## it is in this location, i.e. occ, _occ, or occ.bash: cp --verbose \ From f53b3d6d06409fc98aed0fc14ea215b0443e0284 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Wed, 18 Jan 2023 23:20:16 -0800 Subject: [PATCH 38/47] Allow occ.bash to operate from multiple aliases for admins with multiple Nextcloud instances per machine. Each instance should have its own alias. Signed-off-by: Ronald Barnes --- occ.bash | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/occ.bash b/occ.bash index 135f6a986cccf..6166d226b4f97 100644 --- a/occ.bash +++ b/occ.bash @@ -55,7 +55,7 @@ function _occ_get_opts_list() fi ## Read output of "occ" and get word-chars following "-" or "--": - done <<< $(occ ${appName} | + done <<< $(eval ${occ_alias_name} ${appName} | grep --extended-regex --only-matching " \-(\-|\w)+" ) ## Verbose settings hard to parse: i.e. "-v|vv|vvv, --verbose" @@ -96,7 +96,7 @@ function _occ_get_apps_args_and_opts() local opts opts_list ## Get all output into one var: - args=$(occ ${occCommand} --help --raw 2>&1) + args=$(eval ${occ_alias_name} ${occCommand} --help --raw 2>&1) ## Save a copy and avoid running occ twice (once for args, once for opts): opts=args @@ -166,7 +166,7 @@ function _occ_get_users_list() if [[ ! ${COMP_WORDS[@]} =~ ${value} ]] ; then display_args_arr+=("${value}") fi - done <<< $(occ user:list) + done <<< $(eval ${occ_alias_name} user:list) } @@ -177,7 +177,7 @@ function _occ_get_apps_list() local args value ## Only repopulate apps list if not done already in this instance: if [[ -z ${occ_apps_list} ]] ; then - occ_apps_list=$(occ app:list) + occ_apps_list=$(eval ${occ_alias_name} app:list) fi ## If Previous WORD was an app name, don't reload apps as completion options: if [[ ! ${occ_apps_list[@]} =~ $PWORD ]] ; then @@ -253,7 +253,7 @@ function _occ_get_setting_names() elif [[ ${skip_until_app} == "no" ]] ; then display_args_arr+=("${value}") fi - done <<< $(occ config:list ${app_name} --output plain | + done <<< $(eval ${occ_alias_name} config:list ${app_name} --output plain | grep --extended-regex --only-matching "^ {$space_count}- [[:alnum:]_.-]+" ) } @@ -297,6 +297,13 @@ function _occ_get_languages_list() ## sudo -u $web_server_user php occ function _occ() { + ## When >1 NC installations, each should have own alias pointing to own + ## installation directory. + ## When fetching, say, app list, it's critical that correct alias invoked + ## i.e. Alias `occ` calls main NC v24 & alias `occbclug` calls NC v25 + occ_alias_name=${1} +#echo -e "_occ() occ_alias_name=\"${occ_alias_name}\" " + ## Word being inspected (CWORD==Current WORD, COMP_CWORD is index): local CWORD=${COMP_WORDS[COMP_CWORD]} ## Previous Word being inspected (PWORD==Previous WORD): @@ -338,12 +345,11 @@ function _occ() ## Skip switches that begin with "-": occ_args_arr+=("${occ_args}") fi - done <<< $(occ --raw 2>&1| + done <<< $(eval ${occ_alias_name} --raw 2>&1| ## Starts with alpha-numerics, can include colons, hyphens, _s: grep --extended-regex --only-matching "^[[:alnum:]:_-]+" ) - ## If we're expecing a file path, let readline defaults handle it: if [[ $CWORD == -p || $PWORD =~ "--path" || $CWORD =~ "--path" ]] ; then compgen_skip="yes" @@ -408,3 +414,11 @@ function _occ() } complete -F _occ occ +## If there are multiple NC instances, then edit the +## ~/.bashrc or ~/.bash_aliases file +## and duplicate the alias that `bash-add-alias.sh` created so each has +## a unique name. +## Then, copy the `complete -F _occ` from above and finish it with the other +## alias name for each additional alias. +## Then, source the alias script (`. ~/.bash_aliases` or `source ~/.bashrc`). +## Then, source this script (`. occ.bash` or `source occ.bash`). From 8be0fbc0925c0c8ad88af88739a7a5c057f33c65 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 19 Jan 2023 01:26:18 -0800 Subject: [PATCH 39/47] Check for uid as well as user_id (dav:list-calendars: uid; files-scan: user_id). Signed-off-by: Ronald Barnes --- occ.bash | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/occ.bash b/occ.bash index 6166d226b4f97..71870f3a14a76 100644 --- a/occ.bash +++ b/occ.bash @@ -121,8 +121,10 @@ function _occ_get_apps_args_and_opts() _occ_get_apps_list fi - ## if an arg is "user_id", get list of all users: - if [[ ${args_list[@]} =~ "user_id" ]] ; then + ## If an arg is "user_id", get list of all users: + ## Note: occ dav:list-calendars expects uid, not user_id! + if [[ ${args_list[@]} =~ "user_id" + || ${args_list[@]} =~ "uid" ]] ; then ## Put list of users into array for completing next input _occ_get_users_list fi From 0074f5b9b72279780dae42794af00813ec3ddb9b Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 19 Jan 2023 10:36:22 -0800 Subject: [PATCH 40/47] Removed line of debug code. Signed-off-by: Ronald Barnes --- occ.bash | 1 - 1 file changed, 1 deletion(-) diff --git a/occ.bash b/occ.bash index 71870f3a14a76..ff092c511dcf7 100644 --- a/occ.bash +++ b/occ.bash @@ -304,7 +304,6 @@ function _occ() ## When fetching, say, app list, it's critical that correct alias invoked ## i.e. Alias `occ` calls main NC v24 & alias `occbclug` calls NC v25 occ_alias_name=${1} -#echo -e "_occ() occ_alias_name=\"${occ_alias_name}\" " ## Word being inspected (CWORD==Current WORD, COMP_CWORD is index): local CWORD=${COMP_WORDS[COMP_CWORD]} From a8248dafc5139cc837af472c56062b583416e35e Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 28 Jan 2023 17:59:08 -0800 Subject: [PATCH 41/47] Changed mode to non-executable: must be sourced for alias to persist after script finishes. Signed-off-by: Ronald Barnes --- bash-add-alias.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 bash-add-alias.sh diff --git a/bash-add-alias.sh b/bash-add-alias.sh old mode 100755 new mode 100644 From 295dfc76adba22cbfba3f77e709b4fc5c32fa704 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Sat, 28 Jan 2023 18:02:02 -0800 Subject: [PATCH 42/47] Renamed script to more descriptive name and updated internal usage. Signed-off-by: Ronald Barnes --- bash-add-alias.sh => bash-tab-completion-occ.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename bash-add-alias.sh => bash-tab-completion-occ.sh (99%) diff --git a/bash-add-alias.sh b/bash-tab-completion-occ.sh similarity index 99% rename from bash-add-alias.sh rename to bash-tab-completion-occ.sh index 6caaa2bef234c..9feca3efcdd84 100644 --- a/bash-add-alias.sh +++ b/bash-tab-completion-occ.sh @@ -17,9 +17,9 @@ ## ########################################################################### ## ## Usage: -## . bash-add-alias.sh +## . bash-tab-completion-occ.sh ## or: -## source bash-add-alias.sh +## source bash-tab-completion-occ.sh ## ########################################################################### ## Save original "catch undefined vars" setting: From 06761f4a353b8cbeb98259a707ddc53b45a10bde Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Thu, 2 Feb 2023 17:44:47 -0800 Subject: [PATCH 43/47] Handle 'dav:move-calendar name sourceuid destinationuid'. Must fetch all user names before completing 'name' - which is a calendar name, not a user name. Signed-off-by: Ronald Barnes --- occ.bash | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/occ.bash b/occ.bash index ff092c511dcf7..cdfbe2f5a18dc 100644 --- a/occ.bash +++ b/occ.bash @@ -121,20 +121,31 @@ function _occ_get_apps_args_and_opts() _occ_get_apps_list fi + + ## if an arg is "name", get list of all config setting names, + ## OR, maybe it's dav looking for calendar name (dav:move-calendar): + if [[ ${args_list[@]} =~ "name" ]] ; then + if [[ ${args_list[@]} =~ "sourceuid" ]] ; then + ## If dav:calendar <(cal)name> , AND... + ## we already have a place-holder for <(cal) name>, then get user_id + ## NOTE: occ dav:move-calendar has count of THREE (empty 3rd placeholder) + if [[ ${#COMP_WORDS[@]} -eq 3 ]] ; then + _occ_get_calendar_names + else + _occ_get_users_list + fi + else + ## Put list of users into array for completing next input + _occ_get_setting_names + fi ## If an arg is "user_id", get list of all users: ## Note: occ dav:list-calendars expects uid, not user_id! - if [[ ${args_list[@]} =~ "user_id" + elif [[ ${args_list[@]} =~ "user_id" || ${args_list[@]} =~ "uid" ]] ; then ## Put list of users into array for completing next input _occ_get_users_list fi - ## if an arg is "name", get list of all config setting names: - if [[ ${args_list[@]} =~ "name" ]] ; then - ## Put list of users into array for completing next input - _occ_get_setting_names - fi - ## if an arg is "file", let `readline` defaults handle it: if [[ ${args_list[@]} =~ "file" ]] ; then compgen_skip="yes" @@ -154,6 +165,32 @@ function _occ_get_apps_args_and_opts() } +## If, i.e., dav:move-calendar [name] [sourceuid] [destinationuid]: +function _occ_get_calendar_names() + { + unset -v ${display_args_arr[@]} + _occ_get_users_list + local user_list=(${display_args_arr[@]}) + unset -v display_args_arr + + local value + ## Iterate through all users, gathering list of calendar names: + for (( X=0 ; X<${#user_list[@]} ; X++ )) ; do + while read -r value ; do + ## Strip trailing characters after and including "+" (table corners): + value=${value%%+*} + ## Strip leading table border & blanks: + value=${value#*| } + ## Strip trailing spaces to end of table: + value=${value%% *} + ## Don't include column header (uri) and blanks: + if [[ ! ${value} == uri && ! -z ${value} ]] ; then + display_args_arr+=("${value}") + fi + done <<< $(eval ${occ_alias_name} dav:list-calendars ${user_list[X]}) + done + } + ## Put list of users into array for completing next input function _occ_get_users_list() From 0f4dcb19cdd905e9b41a652fc6ee1ad50798c494 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 13 Feb 2023 23:42:45 -0800 Subject: [PATCH 44/47] Added two script files to build/files-checker.php Signed-off-by: Ronald Barnes --- build/files-checker.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/files-checker.php b/build/files-checker.php index 3092771881140..77968df74abf3 100644 --- a/build/files-checker.php +++ b/build/files-checker.php @@ -60,6 +60,7 @@ 'autotest-js.sh', 'autotest.sh', 'babel.config.js', + 'bash-tab-completion-occ.sh', 'build', 'composer.json', 'composer.lock', @@ -76,6 +77,7 @@ 'jest.config.js', 'lib', 'occ', + 'occ.bash', 'ocm-provider', 'ocs', 'ocs-provider', From 5b6b3c36514b39f80604bffc1aad865017cc4714 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Mon, 13 Feb 2023 23:45:24 -0800 Subject: [PATCH 45/47] Changed references to 'bash-add-alias.sh' to 'bash-tab-completion-occ.sh'. Signed-off-by: Ronald Barnes --- occ.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/occ.bash b/occ.bash index cdfbe2f5a18dc..8ba14b499b3c4 100644 --- a/occ.bash +++ b/occ.bash @@ -1,9 +1,9 @@ #!/bin/bash ## ########################################################################### -## Companion script bash-add-alias.sh will install / invoke this script. +## Companion script bash-tab-completion-occ.sh will install / invoke this script. ## -## bash-add-alias.sh or the user can copy this file to either +## bash-tab-completion-occ.sh or the user can copy this file to either ## /etc/bash_completion.d/ ## or ## ~/.local/share/bash-completion/completions/ @@ -454,7 +454,7 @@ function _occ() complete -F _occ occ ## If there are multiple NC instances, then edit the ## ~/.bashrc or ~/.bash_aliases file -## and duplicate the alias that `bash-add-alias.sh` created so each has +## and duplicate the alias that `bash-tab-completion-occ.sh` created so each has ## a unique name. ## Then, copy the `complete -F _occ` from above and finish it with the other ## alias name for each additional alias. From a9eba833f7b3f85b905d8852da00ceade16b7df2 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Tue, 14 Feb 2023 16:44:25 -0800 Subject: [PATCH 46/47] Indentation was off; spaces not tabs. Signed-off-by: Ronald Barnes --- build/files-checker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/files-checker.php b/build/files-checker.php index 77968df74abf3..501ec77c693f5 100644 --- a/build/files-checker.php +++ b/build/files-checker.php @@ -60,7 +60,7 @@ 'autotest-js.sh', 'autotest.sh', 'babel.config.js', - 'bash-tab-completion-occ.sh', + 'bash-tab-completion-occ.sh', 'build', 'composer.json', 'composer.lock', @@ -77,7 +77,7 @@ 'jest.config.js', 'lib', 'occ', - 'occ.bash', + 'occ.bash', 'ocm-provider', 'ocs', 'ocs-provider', From aa0962d183313bfae678c396ecf6d46cae53c332 Mon Sep 17 00:00:00 2001 From: Ronald Barnes Date: Tue, 28 Feb 2023 21:38:07 -0800 Subject: [PATCH 47/47] Updated documentation for multi-host, multi-alias environments. Signed-off-by: Ronald Barnes --- occ.bash | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/occ.bash b/occ.bash index 8ba14b499b3c4..f94166177fef7 100644 --- a/occ.bash +++ b/occ.bash @@ -453,10 +453,18 @@ function _occ() complete -F _occ occ ## If there are multiple NC instances, then edit the -## ~/.bashrc or ~/.bash_aliases file +## ~/.bashrc or ~/.bash_aliases file ## and duplicate the alias that `bash-tab-completion-occ.sh` created so each has ## a unique name. -## Then, copy the `complete -F _occ` from above and finish it with the other -## alias name for each additional alias. -## Then, source the alias script (`. ~/.bash_aliases` or `source ~/.bashrc`). -## Then, source this script (`. occ.bash` or `source occ.bash`). +## +## Copy or symlink this file to a new name that matches the alias manually +## created in the previous step, saving it in the location: +## ~/.local/share/bash-completion/completions/ +## +## Then, in the new *.bash file, copy the `complete -F _occ` from above and +## finish it with the other alias name for each additional alias. +## +## Next, source the alias script (`. ~/.bash_aliases` or `source ~/.bashrc`). +## +## Finally, source the new script: +## `. $new_alias.bash` or `source $new_alias.bash`.