Advertisement
Guest User

RunInNewHOME

a guest
Dec 13th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 8.90 KB | None | 0 0
  1. #!/bin/bash
  2. #Written by Manuel Iglesias. glesialo@gmail.com
  3.  
  4. CommandName=${0##*/}
  5. ReferenceDirOption="-r"
  6. TempDir=/tmp
  7. ServiceAvailableOptionStr="-sa" # Same value for all 'Application Service' scripts (Check $COMMON_BIN_DIR/DefaultApplications).
  8. ApplicationServiceCommands="DefaultBrowser DefaultBrowser2 DefaultBrowser3" # Commands that exit immediately. $Command makes a request to an already running binary.
  9. IntervalWaitingForApplicationServices=10 # Seconds
  10. HomePlaceHolder=HOMEVALUE
  11. #Xdg dirs: special directories where applications leave config, cache, etc files
  12. #Environment variables: XDG_CACHE_HOME=$HOME/.cache; XDG_CONFIG_HOME=$HOME/.config; XDG_DATA_HOME=$HOME/.local/share
  13. XdgEnvVars="XDG_CACHE_HOME=${HomePlaceHolder}/.cache XDG_CONFIG_HOME=${HomePlaceHolder}/.config XDG_DATA_HOME=${HomePlaceHolder}/.local/share"
  14. SpecialNotDotItemsToLink="Desktop Documents Downloads Music Pictures Public Templates Videos var" # Space separated.
  15. #To override configuration dirs/files create directories/files as needed:
  16. #  NewHOME/Application (or Application.cfg)
  17. #To override Xdg directories, create directories as needed:
  18. #  NewHOME/.cache/ApplicationDir
  19. #  NewHOME/.config/ApplicationDir
  20. #  NewHOME/.local/share/ApplicationDir
  21.  
  22.  
  23.  
  24. echoE()
  25. {
  26. echo -e "#$*" 1>&2
  27. return 0
  28. }
  29.  
  30. Usage()
  31. {
  32. echoE "'$CommandName' changes, temporarily, HOME variable to 'NewHomeDir'"
  33. echoE "and then runs the specified Command with the supplied Arguments."
  34. echoE "'$CommandName' creates links to \$HOME directories and files in:"
  35. echoE "\t'NewHomeDir'"
  36. for SubDir in $XdgDirs
  37.   do
  38.     echoE "\t'NewHomeDir/${SubDir}'"
  39.   done
  40. echoE "Notes:"
  41. echoE "\tAbove links will be removed when Command exits."
  42. echoE "\t'NewHomeDir' must exist."
  43. echoE "\t'NewHomeDir's contents can be updated to those of a"
  44. echoE "\t  reference directory if '$ReferenceDirOption' option is used."
  45. echoE "\tOnly one instance of '$CommandName' can be run for a"
  46. echoE "\t  given, 'NewHomeDir', directory."
  47. echoE
  48. echoE "Usage: '$CommandName NewHomeDir Command [CommandArguments]'."
  49. echoE "or"
  50. echoE "Usage: '$CommandName $ReferenceDirOption ReferenceDir NewHomeDir Command [CommandArguments]'."
  51. echoE
  52. return 0
  53. }
  54.  
  55.  
  56.  
  57. XdgDirs=""
  58. for Item in $XdgEnvVars
  59.   do
  60.     XdgDirs="${Item##*${HomePlaceHolder}/} ${XdgDirs}"
  61.   done # XdgDirs contains ".local/share .config .cache"
  62.  
  63. ReferenceDir="";ReferenceDirOptionUsed=false
  64. if [ "$1" == "$ReferenceDirOption" ]
  65.   then
  66.     ReferenceDirOptionUsed=true
  67.     if [ $# -gt 1 ]
  68.       then
  69.         ReferenceDir="$2"
  70.         shift; shift # '$ReferenceDirOption Dir' parameters removed. Dir in $ReferenceDir.
  71.       else
  72.         echoE "$CommandName: Warning! A directory should follow '$ReferenceDirOption'."
  73.         echoE
  74.         Usage
  75.         exit 64
  76.     fi
  77.     if [ ! -d "$ReferenceDir" ]
  78.       then
  79.         echoE "$CommandName: '$ReferenceDir' is not a valid directory"
  80.         exit 70
  81.     fi
  82. fi
  83. # Now $@ contains "NewHomeDir Command [CommandArguments]"
  84.  
  85. if [ $# -lt 2 ] || [ "$1" == "-h" ] || [ "$1" == "-?" ] || [ "$1" == "--help" ] || [ "$1" == "-help" ]
  86.   then
  87.    Usage
  88.    exit 64
  89. fi
  90.  
  91. if [ ! -d "$1" ]
  92.   then
  93.     echoE "$CommandName: '$1' is not a valid directory"
  94.     exit 70
  95. fi
  96.  
  97. CommandLines="$(ps -C "$CommandName"  h -o pid,command)" # No headers, print pid and commandline.
  98. while read CommandLine
  99.   do
  100.     if [ "${CommandLine%% *}" != "$$" ] # Skip this process commandline.
  101.       then
  102.         if [ "$CommandLine" != "${CommandLine/${0}/}" ] && [ "$CommandLine" != "${CommandLine/${1}/}" ]
  103.           then # CommandLine contains $0 AND $1 (Full path command and NewHomeDir).
  104.             echoE "$CommandName: Instance of '$CommandName' already running for the given directory. Aborting."
  105.             exit 69
  106.         fi
  107.     fi
  108.   done <<<"$CommandLines"
  109.  
  110. OldHome="$HOME"
  111. HOME="$(cd "$1";pwd)" # Expands relative paths
  112.  
  113. if $ReferenceDirOptionUsed
  114.   then
  115.     cd "$ReferenceDir"
  116.     if ! cp --force --recursive --update --target-directory="$HOME" . &>/dev/null
  117.       then
  118.         echoE "$CommandName: Updating from '${ReferenceDir}' failed. Aborting."
  119.         exit 70
  120.       else
  121.         echo "$CommandName: '$HOME' updated from '${ReferenceDir}'."
  122.     fi
  123. fi
  124.  
  125. Command=$2; shift; shift # $@ contains CommandArguments (if any)
  126.  
  127. if ! type "$Command" &>/dev/null # Check if command available
  128.   then
  129.     echoE "$CommandName: Command '$Command' not available."
  130.     exit 127
  131. fi
  132.  
  133. if ! TempDir=$(mktemp -dq $TempDir/$CommandName.XXXXXX) &>/dev/null
  134.   then
  135.     echoE "$CommandName: Can't create temporary directory. Aborting."
  136.     exit 73
  137. fi
  138.  
  139. ItemsToLink="${OldHome}/.*"
  140. for Item in $SpecialNotDotItemsToLink
  141.   do
  142.      ItemsToLink="${OldHome}/${Item} $ItemsToLink"
  143.   done
  144. for Item in $ItemsToLink
  145.   do
  146.     if [ -e "$Item" ] && [ "${Item##*/}" != "." ] && [ "${Item##*/}" != ".." ]
  147.       then
  148.         ln -s "$Item" "$TempDir" &>/dev/null
  149.     fi
  150.   done
  151.  
  152. for Item in "$TempDir"/* "$TempDir"/.*
  153.   do
  154.     if [ -e "$Item" ] && [ "${Item##*/}" != "." ] && [ "${Item##*/}" != ".." ]
  155.       then
  156.         if [ ! -e "$HOME/${Item##*/}" ]
  157.           then
  158.             if [ -h "$HOME/${Item##*/}" ] # If "$HOME/${Item##*/}" is a (broken: doesn't exist: see above) link
  159.               then
  160.                 if ! rm "$HOME/${Item##*/}" &>/dev/null
  161.                   then
  162.                     echoE "$CommandName: Warning: Failed to remove broken link '$HOME/${Item##*/}'."
  163.                 fi
  164.             fi
  165.             if ! ln -s "$Item" "$HOME" &>/dev/null
  166.               then
  167.                 echoE "$CommandName: Warning: Failed to create link '$HOME/${Item##*/}'."
  168.             fi
  169.         fi
  170.     fi
  171.   done
  172.  
  173. for Item in $XdgDirs
  174.   do
  175.     if [ -e "${HOME}/$Item" ] && [ ! -L "${HOME}/$Item" ] # If Item exists in $HOME (NewHomeDir) and it is not a symbolic link
  176.       then
  177.         for SubItem in "$TempDir/$Item"/* "$TempDir/$Item"/.*
  178.           do
  179.             if [ -e "$SubItem" ] && [ "${SubItem##*/}" != "." ] && [ "${SubItem##*/}" != ".." ]
  180.               then
  181.                 if [ ! -e "$HOME/$Item/${SubItem##*/}" ]
  182.                   then
  183.                     if [ -h "$HOME/$Item/${SubItem##*/}" ] # If "$HOME/$Item/${SubItem##*/}" is a (broken: doesn't exist: see above) link
  184.                       then
  185.                         if ! rm "$HOME/$Item/${SubItem##*/}" &>/dev/null
  186.                           then
  187.                             echoE "$CommandName: Warning: Failed to remove broken link '$HOME/$Item/${SubItem##*/}'."
  188.                         fi
  189.                     fi
  190.                     if ! ln -s "$SubItem" "$HOME/$Item" &>/dev/null
  191.                       then
  192.                         echoE "$CommandName: Warning: Failed to create link '$HOME/$Item/${SubItem##*/}'."
  193.                     fi
  194.                 fi
  195.             fi
  196.           done
  197.     fi
  198.   done
  199.  
  200. cd "$HOME"
  201. export HOME
  202. export HOME_VAR_DIR="${HOME}/var" # In case there is a local var folder
  203. for Item in $XdgEnvVars #Export: XDG_CACHE_HOME=$HOME/.cache; XDG_CONFIG_HOME=$HOME/.config; XDG_DATA_HOME=$HOME/.local/share
  204.   do
  205.     export ${Item//${HomePlaceHolder}/$HOME}
  206.   done
  207.  
  208. $Command "$@"
  209. ExitCode=$?
  210.  
  211. ######################
  212. #Special case for 'Application Service' Commands that exit immediately. $Command makes a request to an already running binary.
  213. Temp="$ApplicationServiceCommands";ApplicationServiceCommands=""
  214. for SpecialCommand in $Temp
  215.   do
  216.     ApplicationServiceCommands="${ApplicationServiceCommands}_${SpecialCommand}_" # _$SpecialCommand_ to tell apart names with same base (DefaultBrowser, DefaultBrowser2).
  217.   done
  218. if [ "$ApplicationServiceCommands" != "${ApplicationServiceCommands/_${Command}_/}" ] #If $Command is in $ApplicationServiceCommands
  219.   then
  220.     if Pid=$($Command $ServiceAvailableOptionStr) # Pid of runnig binary
  221.       then # Keep this shell instance running until $Command binary exits.
  222.         while ps --pid=$Pid &>/dev/null
  223.           do
  224.             sleep $IntervalWaitingForApplicationServices
  225.           done
  226.     fi
  227. fi
  228. ######################
  229.  
  230. if ! rm -R "$TempDir" &>/dev/null
  231.  then
  232.    echoE "$CommandName: Warning: '$TempDir' could not be removed."
  233. fi
  234.  
  235. for Item in "$HOME"/* "$HOME"/.*
  236.   do
  237.     if [ -h "$Item" ] && [ ! -e "$Item" ] # If Item is a broken link
  238.       then
  239.         if ! rm "$Item" &>/dev/null
  240.           then
  241.             echoE "$CommandName: Warning: Failed to remove broken link '$Item'."
  242.         fi
  243.     fi
  244.   done
  245.  
  246. for Item in $XdgDirs
  247.   do
  248.     if [ -e "$HOME/$Item" ] && [ ! -L "$HOME/$Item" ] # If Item exists in $HOME (NewHomeDir) and it is not a symbolic link
  249.       then
  250.         for SubItem in "$HOME/$Item"/* "$HOME/$Item"/.*
  251.           do
  252.             if [ -h "$SubItem" ] && [ ! -e "$SubItem" ] # If SubItem is a broken link
  253.               then
  254.                 if ! rm "$SubItem" &>/dev/null
  255.                   then
  256.                   echoE "$CommandName: Warning: Failed to remove broken link '$SubItem'."
  257.                 fi
  258.             fi
  259.           done
  260.     fi
  261.   done
  262.  
  263. exit $ExitCode
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement