linkall 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #! /bin/bash
  2. #
  3. # symlink all files in an src directory to a target directory
  4. #
  5. # usage: link2 [options] srcDir [targetDir]
  6. # -v | --verbose Echo command names
  7. # -d | --debug Additional debugging output
  8. # -h | --help This text
  9. # -n | --dry-run Do not execute
  10. # -r | --remove Remove link/file if it exists
  11. #
  12. # targetDir is created (mkdir -p) if it does not exist. Existing
  13. # symlinks are replaced.
  14. #
  15. # Examples:
  16. #
  17. # Link all files in /etc to ./etc, creating ~./etc if needed
  18. #
  19. # $ linkall -v /etc
  20. #
  21. #
  22. # Link all files in ~/git/public/dotfiles to $HOME, replacing existing links
  23. #
  24. # $ linkall ~/git/public/dotfiles $HOME
  25. #
  26. # Author:
  27. # George Jones
  28. set -e -u
  29. PROG_NAME=$0
  30. PROG_NAME=`basename $0`
  31. SHORT_OPTS='vdhnrs:'
  32. LONG_OPTS='verbose,debug,dry-run,help,remove,stack-size:'
  33. OPTS=`getopt -o $SHORT_OPTS --long $LONG_OPTS -n 'parse-options' -- "$@"`
  34. function usage() {
  35. cat <<END >&2
  36. usage: $PROG_NAME [options] srcDir targetDir
  37. -v | --verbose Echo command names
  38. -d | --debug Additional debugging output
  39. -h | --help This text
  40. -n | --dry-run Do not execute
  41. -r | --remove Remove link/file if it exists
  42. END
  43. exit 1
  44. }
  45. if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
  46. eval set -- "$OPTS"
  47. # Default values
  48. VERBOSE=false
  49. HELP=false
  50. DRY_RUN=false
  51. STACK_SIZE=0
  52. DEBUG=false
  53. REMOVE=false
  54. # Set user selected options
  55. while true; do
  56. case "$1" in
  57. -v | --verbose ) VERBOSE=true; shift ;;
  58. -d | --debug ) DEBUG=true; shift ;;
  59. -h | --help ) HELP=true; shift ;;
  60. -n | --dry-run ) DRY_RUN=true; shift ;;
  61. -r | --remove ) REMOVE=true; shift ;;
  62. -s | --stack-size ) STACK_SIZE="$2"; shift; shift ;;
  63. -- ) shift; break ;;
  64. * ) break ;;
  65. esac
  66. done
  67. if $DEBUG; then
  68. VERBOSE=true
  69. fi
  70. if $DEBUG; then
  71. echo VERBOSE=$VERBOSE
  72. echo DEBUG=$DEBUG
  73. echo HELP=$HELP
  74. echo DRY_RUN=$DRY_RUN
  75. echo REMOVE=$REMOVE
  76. echo STACK_SIZE=$STACK_SIZE
  77. fi
  78. # validate arguments
  79. if [[ "$STACK_SIZE" =~ '"^[0-9]+$' ]]; then
  80. echo "$PROG_NAME: stack_size must be an integer. Got /$STACK_SIZE/" >&2
  81. usage
  82. fi
  83. # get file arguments
  84. if [ "$#" -lt 1 ]; then
  85. echo $PROG_NAME: missing srcDir
  86. usage
  87. fi
  88. if $HELP; then
  89. usage
  90. fi
  91. srcDir=$1
  92. targetDir=${2:-"${PWD}"}
  93. # figure out the link target, make sure it exists
  94. if [ ! -d ${srcDir} ]; then
  95. echo $0: ${srcDir} does not exist or is not a directory>&2
  96. exit 1
  97. fi
  98. # Make sure targetDir exists, creating if necessary
  99. if [ -d `readlink -f "${targetDir}"` ]; then
  100. if $DRY_RUN || $VERBOSE; then
  101. echo ${targetDir} exists
  102. fi
  103. elif [ -e "${targetDir}" ]; then
  104. echo $0: ${targetDir} exists but is not or is not a directory>&2
  105. exit 1
  106. else
  107. if $DRY_RUN || $VERBOSE; then
  108. echo mkdir -p ${targetDir}
  109. fi
  110. mkdir -p "${targetDir}"
  111. fi
  112. # Link all files in $srcDir to $targetDir
  113. cd "$srcDir"
  114. for f in `ls -1 -a`; do
  115. if [ "$f" == '.' ] || [ "$f" == '..' ]; then
  116. continue
  117. fi
  118. if $DRY_RUN || $VERBOSE; then
  119. echo rm -f "$targetDir/$f" || true
  120. fi
  121. rm -f "$targetDir/$f" || true
  122. ln -s "$srcDir/$f" "$targetDir"
  123. done