function symlink_contents_to_dir() { local target="$2" mkdir -p "$target" if [[ -f "$1" ]]; then symlink_to_dir "$1" "$target" elif [[ -L "$1" && ! -d "$1" ]]; then local actual=$(readlink "$1") symlink_contents_to_dir "$actual" "$target" elif [[ -d "$1" ]]; then SAVEIFS=$IFS IFS=$' ' local children=($(find "$1" -maxdepth 1 -mindepth 1)) IFS=$SAVEIFS for child in "${children[@]}"; do symlink_to_dir "$child" "$target" done fi } function symlink_to_dir() { local target="$2" mkdir -p "$target" if [[ -f "$1" ]]; then ln -s -f "$1" "$target" elif [[ -L "$1" && ! -d "$1" ]]; then cp "$1" "$2" elif [[ -d "$1" ]]; then SAVEIFS=$IFS IFS=$' ' local children=($(find "$1" -maxdepth 1 -mindepth 1)) IFS=$SAVEIFS local dirname=$(basename "$1") mkdir -p "$target/$dirname" for child in "${children[@]}"; do symlink_to_dir "$child" "$target/$dirname" done else echo "Can not copy $1" fi } symlink_contents_to_dir $SOURCE_DIR $TARGET_DIR