2013-08-22 100 views
0

我正在研究一個爲通用Linux dotfile安裝腳本工作的bash腳本。我試圖獲得符號鏈接的工作,但我一直在抨擊(沒有雙關語意圖)我的頭靠在牆上試圖找出爲什麼符號鏈接不起作用,並且複製不起作用。我目前有這個分成多個文件,所以我沒有if語句三英里長。Bash是符號鏈接到工作目錄而不是指定的目錄

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中的所有點文件符號鏈接到TEST_DIR。 (TEST_DIR將在生產腳本中爲$ HOME。)理論上很好,對嗎?

當我運行該腳本時出現了複雜情況。沒有任何文件被複制或符號鏈接,因爲它們應該是。相反,我最終沒有複製(可能是因爲符號鏈接不起作用的問題)和當前目錄中的錯誤符號鏈接。

最後一條信息。我正在從包含ultimate-install.sh(/ home/daniel/Projects/Git-Repos/Ultimate-Dotfile-Install-Scripts)的目錄執行該文件。

那麼我哪裏出錯了?

PS請不要評論TODO。 :)

回答

2

簡短的回答

你的報價是錯誤的。

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另一個偉大的答案。請檢查一下!還請閱讀評論,因爲我在那裏解釋你的問題。
+0

我知道我錯過了一些明顯的東西。並感謝您對劇本風格的評論。關閉主題,你有什麼好的指導來學習bash腳本樣式規則嗎?正如你可能知道的,我對bash腳本編程有點新。 – firstofth300

+0

@DaBungalow沒有我所知道的。最重要的是與我提供的答案鏈接。對於其他任何事情,只要嘗試搜索替代方案並選擇最佳方案。通常有多種方法可以在bash中做同樣的事情。 –

+0

好的。再次感謝您的幫助! – firstofth300

相關問題