0

私は、ユニバーサル Linux ドットファイル インストール スクリプト用に取り組んでいる bash スクリプトに取り組んでいます。私はシンボリックリンクを機能させようとしていますが、シンボリックリンクが機能せず、コピーが機能しない理由を理解しようとして、壁に頭をぶつけています(しゃれは意図していません)。私は現在、これを複数のファイルに分けているので、3 マイルの長さの 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、多くの説明を行う長いステートメントのためにトリミングされています。

このスクリプトの基本的な考え方は、最大 2 つの引数 (インストールするドットファイル ディレクトリと、指定されている場合はカスタム バックアップ ディレクトリ、それぞれ $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 についてコメントしないでください。:)

4

1 に答える 1

2

簡潔な答え

あなたの引用は間違っています。

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

より長い答え

これは実際にはあなたの問題とは関係ありませんが、指摘したいと思います。

  • ""inside[[ ]]if [[ -z "$1" ]]; then使用しないでください。if [[ -z $1 ]]; then
  • ディレクトリの末尾にスラッシュがないことを確認するポイントは何ですか? 効果なし!orと/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。チェックアウトしてください!私はあなたの問題を正確に説明していたので、コメントも読んでください。
于 2013-08-22T05:57:37.283 に答える