Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #Written by Manuel Iglesias. glesialo@gmail.com
- CommandName=${0##*/}
- ReferenceDirOption="-r"
- TempDir=/tmp
- ServiceAvailableOptionStr="-sa" # Same value for all 'Application Service' scripts (Check $COMMON_BIN_DIR/DefaultApplications).
- ApplicationServiceCommands="DefaultBrowser DefaultBrowser2 DefaultBrowser3" # Commands that exit immediately. $Command makes a request to an already running binary.
- IntervalWaitingForApplicationServices=10 # Seconds
- HomePlaceHolder=HOMEVALUE
- #Xdg dirs: special directories where applications leave config, cache, etc files
- #Environment variables: XDG_CACHE_HOME=$HOME/.cache; XDG_CONFIG_HOME=$HOME/.config; XDG_DATA_HOME=$HOME/.local/share
- XdgEnvVars="XDG_CACHE_HOME=${HomePlaceHolder}/.cache XDG_CONFIG_HOME=${HomePlaceHolder}/.config XDG_DATA_HOME=${HomePlaceHolder}/.local/share"
- SpecialNotDotItemsToLink="Desktop Documents Downloads Music Pictures Public Templates Videos var" # Space separated.
- #To override configuration dirs/files create directories/files as needed:
- # NewHOME/Application (or Application.cfg)
- #To override Xdg directories, create directories as needed:
- # NewHOME/.cache/ApplicationDir
- # NewHOME/.config/ApplicationDir
- # NewHOME/.local/share/ApplicationDir
- echoE()
- {
- echo -e "#$*" 1>&2
- return 0
- }
- Usage()
- {
- echoE "'$CommandName' changes, temporarily, HOME variable to 'NewHomeDir'"
- echoE "and then runs the specified Command with the supplied Arguments."
- echoE "'$CommandName' creates links to \$HOME directories and files in:"
- echoE "\t'NewHomeDir'"
- for SubDir in $XdgDirs
- do
- echoE "\t'NewHomeDir/${SubDir}'"
- done
- echoE "Notes:"
- echoE "\tAbove links will be removed when Command exits."
- echoE "\t'NewHomeDir' must exist."
- echoE "\t'NewHomeDir's contents can be updated to those of a"
- echoE "\t reference directory if '$ReferenceDirOption' option is used."
- echoE "\tOnly one instance of '$CommandName' can be run for a"
- echoE "\t given, 'NewHomeDir', directory."
- echoE
- echoE "Usage: '$CommandName NewHomeDir Command [CommandArguments]'."
- echoE "or"
- echoE "Usage: '$CommandName $ReferenceDirOption ReferenceDir NewHomeDir Command [CommandArguments]'."
- echoE
- return 0
- }
- XdgDirs=""
- for Item in $XdgEnvVars
- do
- XdgDirs="${Item##*${HomePlaceHolder}/} ${XdgDirs}"
- done # XdgDirs contains ".local/share .config .cache"
- ReferenceDir="";ReferenceDirOptionUsed=false
- if [ "$1" == "$ReferenceDirOption" ]
- then
- ReferenceDirOptionUsed=true
- if [ $# -gt 1 ]
- then
- ReferenceDir="$2"
- shift; shift # '$ReferenceDirOption Dir' parameters removed. Dir in $ReferenceDir.
- else
- echoE "$CommandName: Warning! A directory should follow '$ReferenceDirOption'."
- echoE
- Usage
- exit 64
- fi
- if [ ! -d "$ReferenceDir" ]
- then
- echoE "$CommandName: '$ReferenceDir' is not a valid directory"
- exit 70
- fi
- fi
- # Now $@ contains "NewHomeDir Command [CommandArguments]"
- if [ $# -lt 2 ] || [ "$1" == "-h" ] || [ "$1" == "-?" ] || [ "$1" == "--help" ] || [ "$1" == "-help" ]
- then
- Usage
- exit 64
- fi
- if [ ! -d "$1" ]
- then
- echoE "$CommandName: '$1' is not a valid directory"
- exit 70
- fi
- CommandLines="$(ps -C "$CommandName" h -o pid,command)" # No headers, print pid and commandline.
- while read CommandLine
- do
- if [ "${CommandLine%% *}" != "$$" ] # Skip this process commandline.
- then
- if [ "$CommandLine" != "${CommandLine/${0}/}" ] && [ "$CommandLine" != "${CommandLine/${1}/}" ]
- then # CommandLine contains $0 AND $1 (Full path command and NewHomeDir).
- echoE "$CommandName: Instance of '$CommandName' already running for the given directory. Aborting."
- exit 69
- fi
- fi
- done <<<"$CommandLines"
- OldHome="$HOME"
- HOME="$(cd "$1";pwd)" # Expands relative paths
- if $ReferenceDirOptionUsed
- then
- cd "$ReferenceDir"
- if ! cp --force --recursive --update --target-directory="$HOME" . &>/dev/null
- then
- echoE "$CommandName: Updating from '${ReferenceDir}' failed. Aborting."
- exit 70
- else
- echo "$CommandName: '$HOME' updated from '${ReferenceDir}'."
- fi
- fi
- Command=$2; shift; shift # $@ contains CommandArguments (if any)
- if ! type "$Command" &>/dev/null # Check if command available
- then
- echoE "$CommandName: Command '$Command' not available."
- exit 127
- fi
- if ! TempDir=$(mktemp -dq $TempDir/$CommandName.XXXXXX) &>/dev/null
- then
- echoE "$CommandName: Can't create temporary directory. Aborting."
- exit 73
- fi
- ItemsToLink="${OldHome}/.*"
- for Item in $SpecialNotDotItemsToLink
- do
- ItemsToLink="${OldHome}/${Item} $ItemsToLink"
- done
- for Item in $ItemsToLink
- do
- if [ -e "$Item" ] && [ "${Item##*/}" != "." ] && [ "${Item##*/}" != ".." ]
- then
- ln -s "$Item" "$TempDir" &>/dev/null
- fi
- done
- for Item in "$TempDir"/* "$TempDir"/.*
- do
- if [ -e "$Item" ] && [ "${Item##*/}" != "." ] && [ "${Item##*/}" != ".." ]
- then
- if [ ! -e "$HOME/${Item##*/}" ]
- then
- if [ -h "$HOME/${Item##*/}" ] # If "$HOME/${Item##*/}" is a (broken: doesn't exist: see above) link
- then
- if ! rm "$HOME/${Item##*/}" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to remove broken link '$HOME/${Item##*/}'."
- fi
- fi
- if ! ln -s "$Item" "$HOME" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to create link '$HOME/${Item##*/}'."
- fi
- fi
- fi
- done
- for Item in $XdgDirs
- do
- if [ -e "${HOME}/$Item" ] && [ ! -L "${HOME}/$Item" ] # If Item exists in $HOME (NewHomeDir) and it is not a symbolic link
- then
- for SubItem in "$TempDir/$Item"/* "$TempDir/$Item"/.*
- do
- if [ -e "$SubItem" ] && [ "${SubItem##*/}" != "." ] && [ "${SubItem##*/}" != ".." ]
- then
- if [ ! -e "$HOME/$Item/${SubItem##*/}" ]
- then
- if [ -h "$HOME/$Item/${SubItem##*/}" ] # If "$HOME/$Item/${SubItem##*/}" is a (broken: doesn't exist: see above) link
- then
- if ! rm "$HOME/$Item/${SubItem##*/}" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to remove broken link '$HOME/$Item/${SubItem##*/}'."
- fi
- fi
- if ! ln -s "$SubItem" "$HOME/$Item" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to create link '$HOME/$Item/${SubItem##*/}'."
- fi
- fi
- fi
- done
- fi
- done
- cd "$HOME"
- export HOME
- export HOME_VAR_DIR="${HOME}/var" # In case there is a local var folder
- for Item in $XdgEnvVars #Export: XDG_CACHE_HOME=$HOME/.cache; XDG_CONFIG_HOME=$HOME/.config; XDG_DATA_HOME=$HOME/.local/share
- do
- export ${Item//${HomePlaceHolder}/$HOME}
- done
- $Command "$@"
- ExitCode=$?
- ######################
- #Special case for 'Application Service' Commands that exit immediately. $Command makes a request to an already running binary.
- Temp="$ApplicationServiceCommands";ApplicationServiceCommands=""
- for SpecialCommand in $Temp
- do
- ApplicationServiceCommands="${ApplicationServiceCommands}_${SpecialCommand}_" # _$SpecialCommand_ to tell apart names with same base (DefaultBrowser, DefaultBrowser2).
- done
- if [ "$ApplicationServiceCommands" != "${ApplicationServiceCommands/_${Command}_/}" ] #If $Command is in $ApplicationServiceCommands
- then
- if Pid=$($Command $ServiceAvailableOptionStr) # Pid of runnig binary
- then # Keep this shell instance running until $Command binary exits.
- while ps --pid=$Pid &>/dev/null
- do
- sleep $IntervalWaitingForApplicationServices
- done
- fi
- fi
- ######################
- if ! rm -R "$TempDir" &>/dev/null
- then
- echoE "$CommandName: Warning: '$TempDir' could not be removed."
- fi
- for Item in "$HOME"/* "$HOME"/.*
- do
- if [ -h "$Item" ] && [ ! -e "$Item" ] # If Item is a broken link
- then
- if ! rm "$Item" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to remove broken link '$Item'."
- fi
- fi
- done
- for Item in $XdgDirs
- do
- if [ -e "$HOME/$Item" ] && [ ! -L "$HOME/$Item" ] # If Item exists in $HOME (NewHomeDir) and it is not a symbolic link
- then
- for SubItem in "$HOME/$Item"/* "$HOME/$Item"/.*
- do
- if [ -h "$SubItem" ] && [ ! -e "$SubItem" ] # If SubItem is a broken link
- then
- if ! rm "$SubItem" &>/dev/null
- then
- echoE "$CommandName: Warning: Failed to remove broken link '$SubItem'."
- fi
- fi
- done
- fi
- done
- exit $ExitCode
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement