指向尚不存在的文件的符号链接

指向尚不存在的文件的符号链接

我目前正在尝试通过将 、 等文件移动到我的主目录中的目录来清理我的.vimrc主目录.bash_profile.dotfiles

这个想法是随后使用这些文件的符号链接: ln -s ~/.dotfiles/.vimrc ~/.
这工作得很好,但我想通过编写来自动化这个过程我的第一次bash 脚本,我遇到了一些麻烦。

该脚本目前看起来像这样:

#!//bin/bash
# Make script executable with: chmod u+x brew.sh

# Ask for the administrator password upfront.
sudo -v

# Keep-alive: update existing `sudo` time stamp until the script has finished.
while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &

# Create '.other'-folder
echo "--> ~/.other"
if [ -d ~/.other ];
then
  echo "Directory ~/.other exists..."
else
  echo "Creating directory ~/.other..."
  mkdir ~/.other
fi
echo ""

# TRASH
echo "--> ~/.Trash"
if [ -d ~/.Trash ];
then
  echo "Directory ~/.Trash does exists. Moving it to ~/.other..."
  mv ~/.Trash ~/.other/
else
  echo "Directory ~/.Trash doesn't exists. Creating it in ~/.other..."
  mkdir ~/.other/.Trash
fi

echo "Linking ~/.other/.Trash to ~/.Trash..."
ln -s ~/.other/.Trash ~/.
echo ""

# BASH_HISTORY
echo "--> ~/.bash_history"
if [ -a ~/.bash_history ];
then
  echo "File ~/.bash_history does exists. Moving it to ~/.other..."
  mv ~/.bash_history ~/.other/
else
  echo "File ~/.bash_history doesn't exists. Creating it in ~/.other..."
  touch ~/.other/.bash_history
fi

echo "Linking ~/.other/.bash_history to ~/.bash_history..."
ln -s ~/.other/.bash_history ~/.
echo ""

# BASH_SESSIONS
echo "--> ~/.bash_sessions"
if [ -d ~/.bash_sessions ];
then
  echo "Directory ~/.bash_history does exists. Moving it to ~/.other..."
  mv ~/.bash_sessions ~/.other/
else
  echo "Directory ~/.bash_history doesn't exists. Creating it in ~/.other..."
  mkdir ~/.other/.bash_sessions
fi

echo "Linking ~/.other/.bash_sessions/ to ~/.bash_sessions/..."
ln -s ~/.other/.bash_sessions ~/.
echo ""

# .LOCAL
echo "--> ~/.local"
if [ -d ~/.local ];
then
  echo "Directory ~/.local does exists. Moving it to ~/.other..."
  mv ~/.local ~/.other/
else
  echo "Directory ~/.local doesn't exists. Creating it in ~/.other..."
  mkdir ~/.other/.local
fi

echo "Linking ~/.other/.local/ to ~/.local/..."
ln -s ~/.other/.local ~/.
echo ""

# .CONFIG
echo "--> ~/.config"
if [ -d ~/.config ];
then
  echo "Directory ~/.config does exists. Moving it to ~/.other..."
  mv ~/.config ~/.other/
else
  echo "Directory ~/.config doesn't exists. Creating it in ~/.other..."
  mkdir ~/.other/.config
fi

echo "Linking ~/.other/.config/ to ~/.config/..."
ln -s ~/.other/.config ~/.
echo ""

正如您所看到的,代码非常重复,但首先是重要的事情。代码应该大致像这样工作。检查init.vim我的主目录中是否存在文件(例如)。如果确实存在,请将其移至~/.other(不那么重要的文件) 或者~/.dotfiles重要文件)。如果不存在,则在~/.dotfiles或中创建一个文件(或目录) ~/.other。之后的符号链接。

到目前为止的理论。问题是,如果我的主目录中尚不存在该文件 - 脚本只会在~/.dotfiles/中创建一个文件~/.other,并将主目录中的名称链接到它。这在实践中并没有真正发挥作用,因为某些文件需要特定的权限。例如,neovim如果某些文件是使用此脚本创建的,则无法识别它们,并且在使用文件之前创建文件的效率也不是很高。

有没有办法解决这个问题(例如,通过创建链接,而不创建目标文件 - 我尝试过一次链接.bash_history.other/.bash_history,链接工作正常,但bash无法写入不存在的文件)?如果新文件是最佳的已创建在里面正确的地点,我只需要指定正确的之前放置?

PS:当文件已经存在时,脚本可以正常工作(它只是将文件移动到新位置并链接它)。

答案1

重写以减少重复

#!/bin/bash
# Make script executable with: chmod u+x brew.sh

# Ask for the administrator password upfront.
sudo -v

# Keep-alive: update existing `sudo` time stamp until the script has finished.
while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &

# Create '.other'-folder
echo "--> ~/.other"
mkdir -p ~/.other 2>/dev/null
echo ""

create_dir() {
    local pathname=$1 destination=$2 permissions=$3
    local dirname=$(basename "$pathname")

    echo "--> $pathname"
    if [ -L "$pathname" ] && [ "$(dirname "$(readlink "$pathname")")" = "$destination" ]; then
        echo "$pathname is already a symbolic link to $destination/$filename"
        return
    elif [ -d "$pathname" ]; then
        echo "Directory $pathname exists. Moving it to $destination..."
        mv "$pathname" $destination/
    else
        echo "Directory $pathname doesn't exist Creating it in $destination..."
        mkdir -p "$destination/$dirname"
    fi
    chmod "$permissions" "$destination/$direname"

    echo "Linking $destination/$dirname to $pathname ..."
    (
        cd "$(dirname "$pathname")"
        ln -s "$destination/$dirname" 
    )
    echo
}

create_file() {
    local pathname=$1 destination=$2 permissions=$3
    local filename=$(basename "$pathname")
    echo "--> $pathname"
    if [ -L "$pathname" ] && [ "$(dirname "$(readlink "$pathname")")" = "$destination" ]; then
        echo "$pathname is already a symbolic link to $destination/$filename"
        return
    elif [ -a "$pathname" ]; then
        echo "File $pathname exists. Moving it to $destination..."
        mv "$pathname" $destination/
    else
        echo "File $pathname doesn't exists. Creating it in $destination..."
        touch "$destination/$filename"
    fi
    chmod "$permissions" "$destination/$filename"

    echo "Linking $destination/$filename to ~/.bash_history..."
    (
        cd "$(dirname "$pathname")"
        ln -s "$destination/$filename"
    )
    echo ""
}

create_dir   ~/.Trash          ~/.other  755   # TRASH
create_file  ~/.bash_history   ~/.other  600   # BASH_HISTORY
create_file  ~/.bash_sessions  ~/.other  644   # BASH_SESSIONS
create_dir   ~/.local          ~/.other  755   # .LOCAL
create_dir   ~/.config         ~/.other  755   # .CONFIG

create_file  ~/.bashrc         ~/.dotfiles 644 # etc ...

笔记:

  • mkdir -p如果目录不存在,将创建该目录
  • 首先检查目录/文件是否还不是符号链接。
  • 如果特定文件需要特定权限,则别无选择,只能指定它。

相关内容