スクリプトを実行して、システムに適用された変更を元に戻すシェルスクリプトを作成します。

スクリプトを実行して、システムに適用された変更を元に戻すシェルスクリプトを作成します。

質問:

スクリプトを実行して変更をキャンセルするには、スクリプトを作成する必要がありますか?

そうでない場合は、システムに適用された変更をクリーンアップ/アンドゥアンドラインで次の操作を実行できますか?スクリプトを実行する前に、システム状態でスクリプトを再実行(変更)してください。

それでは、良いUNDOスクリプトを書くにはどのようなアプローチを取るべきですか?


スクリプト:githubのスクリプトリンク

#!bin/bash

repos_dir="$HOME/repos"
if [ ! -d "$repos_dir" ]; then
  mkdir -p "$repos_dir"
fi

git clone https://github.com/bashonregardless/dotfiles.git "$repos_dir/dotfiles"

software_dir="$HOME/software"
# Create a directory to download nvim software.
if test ! -d "$software_dir"; then
  mkdir "$software_dir"
fi

(
cd "$software_dir"
# Download Neovim on Linux
if test $? = 0 && "$(command -v curl)" &> dev/null; then
  curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
  chmod u+x nvim.appimage
else
  echo "Error: curl is not installed"
  echo
  exit 64
fi
)

# Create "$HOME/bin" dir if it does not exist
if test ! -d "$HOME/bin"
then
    mkdir "$HOME/bin"
fi

# Create a symbolic link in "$HOME/bin" dir to "$HOME/software/nvim"
ln "$software_dir/nvim.appimage" "$HOME/bin/nvim"

# Update vimrc at "$HOME/.vim/vimrc"
[ ! -d "$HOME/.vim" ] && mkdir "$HOME/.vim"
if [ ! -e "$HOME/.vim/vimrc" ]; then
    # create a new file by copying dotfile vimrc
    cp "$repos_dir/dotfiles/vimrc.template" "$HOME/.vim/vimrc"
else
    cat "$repos_dir/dotfiles/vimrc.template" >> "$HOME/.vim/vimrc" 
fi

# Update init.vim at "$HOME/.config/nvim/" (VIMCONFIG="$HOME/.config/nvim")
[ ! -d "$HOME/.config/nvim" ] && mkdir -p "$HOME/.config/nvim"
if [ ! -e "$HOME/.config/nvim/init.vim" ]; then
    # create a new file by copying dotfile vimrc
    cp "$repos_dir/dotfiles/init.vim.template" "$HOME/.config/nvim/init.vim"
else
    cat "$repos_dir/dotfiles/init.vim.template" >> "$HOME/.config/nvim/init.vim" 
fi

# add minpac vim plugin manager (See Modern vim craft)
[ ! -d "$HOME/.config/nvim/pack/minpac/opt" ] && mkdir -p "$HOME/.config/nvim/pack/minpac/opt"
cd "$HOME/.config/nvim/pack/minpac/opt"
git clone https://github.com/k-takata/minpac.git
cd -

# Update dotfiles (create, if non-existent)
if [ ! -e "$HOME/.bash_profile" ]; then
    # Copy and rename in the same time
    cp "$repos_dir/dotfiles/bash_profile" "$HOME/.bash_profile"
else
    cat "$repos_dir/dotfiles/bash_profile" >> "$HOME/.bash_profile" 
fi

if [ ! -e "$HOME/.bashrc" ]; then
    cp "$repos_dir/dotfiles/bashrc" "$HOME/.bashrc"
else
    cat "$repos_dir/dotfiles/bashrc" >> "$HOME/.bashrc" 
fi

このスクリプトはvim開発環境を設定します。スクリプトを書いて正しく設定すれば十分だと思って初めて実行してみましたが、うまくいきました。その後、スクリプトをいくつか変更し、正しく実行されているかどうかをテストしたいと思いました。今回の実行中に、次の警告/エラー/ログが発生しました。

ln: '/home/user/bin/nvim' ハードリンクを作成できません: ファイルが存在します。

致命的:ターゲットパス '/home/user/repos/dotfiles'が既に存在し、空のディレクトリではありません。

いくつか書いてみましたcat file >> another-fileanother-fileスクリプトが実行されるたびに、重複したコンテンツが追加されます。私はこれを必ずキャンセルしたい


スクリプトを実行してシステムに変更を適用しました。

  1. ~/repos ディレクトリを作成します。
  2. リポジトリからdotfilesリポジトリを複製します。
  3. リポジトリから compSc リポジトリを複製します。
  4. 自宅でソフトウェアカタログを作成します。
  5. ソフトウェアディレクトリからnvimをダウンロードします。
  6. ダウンロードしたファイルnvim.appimageの権限を変更します。
  7. 自宅にbinディレクトリを作成します。
  8. ~/bin/nvim を使用して nvim.appimage へのシンボリックリンクを作成します。
  9. ~/.vim/vimrc(mkdir -p) を生成します。
  10. ~/.vim/vimrcにコピー/作成または追加します。
  11. mkdir -p "$HOME/.config/nvim/pack/minpac/opt"
  12. k-takata/minpac indside "$HOME/.config/nvim/pack/minpac/opt" 複製
  13. "$HOME/.bash_profile"にコピー/作成または追加

これは〜/.bash_profileファイルをインポートする前に私のシステムに適用された変更です。ソーシングは、PATHやその他の環境変数の更新など、私のシステムをさらに変更しました。

また、これらの変更をキャンセルしたいと思います。


テスト目的でスクリプトを実行する前に、システムの状態をどのように複製できますか?

私は使う複数回通過小さな変更があるたびにUbuntu VMを起動します。スクリプトを実行した後、仮想マシンを削除して新しい仮想マシンを起動しました。これにより、初めてスクリプトを実行できる状態のマシンが提供されます。私は小さな変化があるたびにこれを行います。早く退屈します。

答え1

通常、スクリプト効果は確実に元に戻すことはできません。たとえば、スクリプトの先頭のコードスニペットは次のとおりです。

if [ ! -d "$repos_dir" ]; then
  mkdir -p "$repos_dir"
fi

以前にどのくらいのディレクトリパスが存在したか後でわからないため、確実に元に戻すことはできません"$repos_dir"

スクリプトを完全にキャンセルできないようにするには、必要に応じて復元できるようにタッチする前に、タッチするすべてのアイテムの元の状態を記録する必要があります。これは、パッケージマネージャがさまざまなレベルの成功を試みるものです。

もう一つの方法はスクリプトを持つことです等級。つまり、2回実行すると、1回実行するのと同じ効果が得られます。これは、Ansible や Puppet などのステートフル構成管理ツールへのアプローチです。

"$repos_dir"上記のコードスニペットは、等級コードの典型的な例です。最後の実行でディレクトリがすでに存在している場合は、何もしません。

コードサンプルはいいえcat file >> another-file等級は、スクリプトを実行するたびに重複コンテンツを追加する場合です。等価性を持たせるには、コンテンツ(または他のバージョン)が既に存在していることをanother-file確認してから、そのコンテンツを最初に削除または再追加しないでください。または、コンテンツなしでデフォルトのバージョンを維持し、それを使用して次のように接続できます。fileanother-fileanother-filefile

if [ ! -e another-file.base ]; then
  mv another-file another-file.base
fi
cat another-file.base file > another-file

関連情報