Bash是符号链接到工作目录而不是指定目录

时间:2013-08-22 05:42:46

标签: linux bash shell symlink

我正在研究一个bash脚本,我正在研究一个通用的Linux dotfile安装脚本。我试图让symlinking工作,但我一直在抨击(没有双关语)我的头撞墙,试图弄清楚为什么符号链接不起作用,复制将无法正常工作。我目前将它分成多个文件,所以我没有if语句三英里长。

ultimate-install.sh

#! /bin/bash
#
# The ultimate install script for all dotfiles.

if [[ -z "$1" ]]; then
    echo "Please specify the directory where all of you dotfiles are located."
    exit 1
fi

# Makes sure that the directory does NOT have a trailing slash!
if [[ ${1:(-1)} == "/" ]]; then
    DOTFILE_DIR=${1:0:${#1} - 1}
else
    DOTFILE_DIR="$1"
fi

# TODO: Clean this mess up and make it more concise.
if [[ -z "$2" ]]; then
    if [[ ! -d $HOME/.config/old_dotfiles ]]; then
        mkdir "$HOME/.config/old_dotfiles"
    fi
    BACKUP_DIR="$HOME/.config/old_dotfiles"
else
    if [[ -d "$2" ]]; then
        BACKUP_DIR="$2"
    else
        mkdir "$2"
        BACKUP_DIR="$2"
    fi
fi

read DECISION

if [ $DECISION == "N" -o $DECISION == "n" ]; then
    echo "Aborting installation!"
    exit
fi

read DECISION

echo

if [ $DECISION == "N" -o $DECISION == "n" ]; then
    source src/no-prompts.sh "$DOTFILE_DIR" "$BACKUP_DIR"
else
    source src/prompts.sh "$DOTFILE_DIR" "$BACKUP_DIR"
fi

echo "Installation complete.  Old dotfiles are backed up to $BACKUP_DIR."

的src / no-prompts.sh

#! /bin/bash
#
# Maintained by Daniel Seymour

DOTFILE_DIR="$1"
BACKUP_DIR="$2"
TEST_DIR="/home/daniel/dotfile-test"

function no_prompt_install(){
    FILE_NAME="$1"
    if [ "${FILE_NAME:0:1}" == "." ]; then
        ln -s "$FILE_NAME $TEST_DIR/$FILE_NAME"
    else
        ln -s ".$FILE_NAME $TEST_DIR/$FILE_NAME"
    fi
}

# TODO: implement a check for file type and deal with unknown files.
for FILE in $DOTFILE_DIR/*; do
    cp $FILE $BACKUP_DIR
    no_prompt_install $FILE
done

的src / prompts.sh

#! /bin/bash
#
# Maintained by Daniel Seymour

DOTFILE_DIR="$1"
BACKUP_DIR="$2"
TEST_DIR="/home/daniel/dotfile-test"

function prompt_install {
    FILE_PATH=$1
    FILE_NAME=${FILE_PATH##*/}
    echo "Would you like to install $FILE_NAME? [Y, n]"
    read DECISION
    if [ $DECISION == "n" -o $DECISION == "N" ]; then
        echo "Not installing."
        return
    else
        # TODO: Clean this up into one statement.
        if [ ${FILE_NAME:0:1} == "." ]; then
            rm -rf "$TEST_DIR/$FILE_NAME"
            ln -sn "$FILE_PATH $TEST_DIR/$FILE_NAME"
        else
            FILE_NAME="."$FILE_NAME
            rm -rf "$TEST_DIR/$FILE_NAME"
            ln -sn "$FILE_PATH $TEST_DIR/$FILE_NAME"
        fi
    fi
}

# TODO: implement a check for file type and deal with unknown files.
for FILE in $DOTFILE_DIR/*; do
    cp $FILE $BACKUP_DIR
    prompt_install $FILE
done

对于进行了大量解释的长echo语句,上面的内容会被修剪。

此脚本的基本思想是获取多达两个参数(要安装的dotfile目录,如果指定,则为自定义备份目录,分别为$ 1和$ 2)。然后,该脚本应将目标目录中的所有文件复制到BACKUP_DIR,并将DOTFILE_DIR中的所有dotfiles符号链接到TEST_DIR。 (TEST_DIR将在制作脚本中为$ HOME。)理论上很棒,对吧?

当我运行脚本时会出现复杂情况。没有任何文件被复制或符号链接。相反,我最终没有副本(可能是由于与符号链接无法正常工作相同的问题)和当前目录中的符号链接损坏。

最后一条信息。我正在从包含ultimate-install.sh(/ home / daniel / Projects / Git-Repos / Ultimate-Dotfile-Install-Scripts)的目录中执行该文件。

那我哪里出错了?

PS请不要对TODO发表评论。 :)

1 个答案:

答案 0 :(得分:2)

简短回答

你的报价错了。

ln -sn -- "$FILE_PATH" "$TEST_DIR/$FILE_NAME"

更长的答案

这与您的问题无关,但我想指出它。

  • 请勿在{{1​​}}内使用"",因此请使用此[[ ]]
  • 代替此if [[ -z "$1" ]]; then
  • 确保目录没有尾部斜杠有什么意义?它没有效果! if [[ -z $1 ]]; then/usr/bin//usr/bin/usr////bin
  • 位于同一目录中
  • 创建目录时不要检查目录是否存在。使用/usr////////bin//////选项!示例:-p
  • 而不是mkdir -p "$HOME/.config/old_dotfiles"使用if [ $DECISION == "N" -o $DECISION == "n" ];
  • 我对bash代码样式HERE有另一个很好的答案。请检查一下!另请阅读评论,因为我正在解释您的问题。