【问题标题】:Bash is symlinking to working directory instead of specified directoryBash 符号链接到工作目录而不是指定目录
【发布时间】:2013-08-22 05:42:46
【问题描述】:

我正在编写一个 bash 脚本,我正在为通用 Linux 点文件安装脚本编写该脚本。我试图让符号链接工作,但我一直在抨击(不是双关语)我的头靠在墙上试图弄清楚为什么符号链接不起作用并且复制不起作用。我目前把它分成多个文件,所以我没有三英里长的 if 语句。

终极安装.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 语句进行了删减,这些语句做了很多解释。

这个脚本的基本思想是最多接受两个参数(要安装的点文件目录,如果指定的话,自定义备份目录,分别为 $1 和 $2)。然后脚本应该将目标目录中的所有文件复制到 BACKUP_DIR 并将 DOTFILE_DIR 中的所有点文件符号链接到 TEST_DIR。 (TEST_DIR 在生产脚本中将是 $HOME。)理论上很好,对吧?

当我运行脚本时,问题就来了。没有文件按照应有的方式复制或符号链接。相反,我最终没有复制(可能是由于与符号链接不工作相同的问题)和当前目录中的符号链接损坏。

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

那么我哪里做错了?

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

【问题讨论】:

    标签: linux bash shell symlink


    【解决方案1】:

    简答

    你的引用是错误的。

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

    更长的答案

    这和你的问题没有关系,但我想指出来。

    • 请勿在[[ ]] 中使用"",因此请使用此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" ]; 使用if [[ ${DECISION^^} == N]];
    • 关于 bash 代码样式HERE,我有另一个很好的答案。请检查一下!还请阅读 cmets,因为我在那里准确地解释了您的问题。

    【讨论】:

    • 我知道我遗漏了一些明显的东西。感谢您对脚本风格的批评。题外话,你有学习 bash 脚本样式规则的好指南吗?您可能会说,我对 bash 脚本有点陌生。
    • @DaBungalow 据我所知没有。最重要的东西在我提供的答案的链接中。对于其他一切,只需尝试搜索替代方案并选择最好的一个。通常在 bash 中有不止一种方法可以做同样的事情。
    • 好的。再次感谢您的帮助!
    • @DaBungalow 这个网站有非常棒的关于 bash 的信息 mywiki.wooledge.org
    猜你喜欢
    • 2016-04-08
    • 1970-01-01
    • 2019-06-30
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多