まだ存在しないファイルへのシンボリックリンク

まだ存在しないファイルへのシンボリックリンク

現在、などのファイルを自分のホームディレクトリ内のディレクトリに移動して.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ディレクトリが存在しない場合は作成されます。
  • まず、ディレクトリ/ファイルがすでにシンボリックリンクではないことを確認してください。
  • 特定のファイルに特定の権限が必要な場合は、それを指定するしかありません。

関連情報