Unix & Linux Asked by Drake P on November 6, 2021
I use git to track my dotfiles across multiple machines. I wrote a pretty simple script in the repo, which backs up any outdated existing dotfiles and then creates symbolic links to each of the up-to-date dotfiles. Here is the script:
#!/bin/bash
############################
# makesymlinks.sh
# This script creates symlinks from the home directory to any desired dotfiles in ~/dotfiles
############################
########## Variables
dir=~/dotfiles # dotfiles directory
olddir=~/dotfiles_old # old dotfiles backup directory
files="bash_aliases bashrc vimrc" # list of files/folders to symlink in homedir
##########
# create dotfiles_old in homedir
echo "Creating $olddir for backup of any existing dotfiles in ~"
mkdir -p $olddir
# move any existing dotfiles in homedir to dotfiles_old directory, then create symlinks
echo "Moving any existing dotfiles from ~ to $olddir"
for file in $files; do
if [ -f ~/."$file" ]; then
mv -n ~/."$file" ~/dotfiles_old/ #-n option means don't overwrite existing files in dotfiles_old
fi
#if e.g. ~/.vimrc exists after mv command, then this script must've been run before w/ .vimrc included
if [ -f ~/."$file" ]; then
echo "Symlink to $dir/$file already exists"
else
echo "Creating symlink to $dir/$file in ~"
ln -s $dir/"$file" ~/."$file"
fi
done
# source .bashrc
printf "nTo complete the setup, please run the following command:nn"
printf "tsource ~/.bashrcnn"
This script normally works just fine. Today though I started working on a new machine (remotely through TeamViewer if that matters), and when I ran this script for the first time, it deleted the directory it was in. I have no idea how it could’ve done that given the script I wrote, and it worked correctly the second time I ran it (after re-cloning the repository again). What went wrong, and how can I fix it? Was this somehow git’s fault? Here’s what my bash terminal looked like surrounding the bug (I’ve added some commentary with bash comments here for clarity):
drakeprovost@shatterdome:~/RoverCoreOS$ git clone https://github.com/DrakeProvost/dotfiles.git
Cloning into 'dotfiles'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 42 (delta 21), reused 29 (delta 11), pack-reused 0
Unpacking objects: 100% (42/42), done.
drakeprovost@shatterdome:~/RoverCoreOS$ cd dotfiles/
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ls
bash_aliases bashrc makesymlinks.sh README.md vimrc
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ./makesymlinks.sh
Creating /home/drakeprovost/dotfiles_old for backup of any existing dotfiles in ~
Moving any existing dotfiles from ~ to /home/drakeprovost/dotfiles_old
Creating symlink to /home/drakeprovost/dotfiles/bash_aliases in ~
Creating symlink to /home/drakeprovost/dotfiles/bashrc in ~
Creating symlink to /home/drakeprovost/dotfiles/vimrc in ~
To complete the setup, please run the following command:
source ~/.bashrc
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ls
bash_aliases bashrc makesymlinks.sh README.md vimrc
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ cd
drakeprovost@shatterdome:~$ ls -al #.bashrc, .vimrc, and .bash_aliases were all red symlinks here, meaning they pointed to non-existent files. Also note that the dotfiles directory has disappeared
total 144
drwxr-xr-x 26 drakeprovost drakeprovost 4096 Jul 19 22:40 .
drwxr-xr-x 12 root root 4096 Sep 24 2019 ..
lrwxrwxrwx 1 drakeprovost drakeprovost 40 Jul 19 22:40 .bash_aliases -> /home/drakeprovost/dotfiles/bash_aliases
-rw------- 1 drakeprovost drakeprovost 11400 Feb 27 20:01 .bash_history
-rw-r--r-- 1 drakeprovost drakeprovost 220 Sep 17 2019 .bash_logout
lrwxrwxrwx 1 drakeprovost drakeprovost 34 Jul 19 22:40 .bashrc -> /home/drakeprovost/dotfiles/bashrc
drwx------ 15 drakeprovost drakeprovost 4096 Oct 15 2019 .cache
drwxr-xr-x 5 drakeprovost drakeprovost 4096 Feb 20 18:08 catkin_ws
drwxr-xr-x 5 drakeprovost drakeprovost 4096 Feb 27 19:23 catkin_ws_PMCurdf
drwx------ 13 drakeprovost drakeprovost 4096 Feb 27 18:57 .config
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Desktop
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Documents
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Jul 19 22:40 dotfiles_old
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Downloads
-rw-r--r-- 1 drakeprovost drakeprovost 8980 Sep 17 2019 examples.desktop
drwx------ 2 drakeprovost drakeprovost 4096 Oct 15 2019 .gconf
drwx------ 3 drakeprovost drakeprovost 4096 Oct 15 2019 .gnupg
-rw------- 1 drakeprovost drakeprovost 2052 Jul 19 22:31 .ICEauthority
drwx------ 3 drakeprovost drakeprovost 4096 Oct 15 2019 .local
drwx------ 5 drakeprovost drakeprovost 4096 Oct 15 2019 .mozilla
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Music
drwx------ 6 drakeprovost drakeprovost 4096 Jul 19 22:31 .nx
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Pictures
-rw-r--r-- 1 drakeprovost drakeprovost 807 Sep 17 2019 .profile
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Public
drwx------ 2 drakeprovost drakeprovost 4096 Jul 19 22:31 .qt
drwxr-xr-x 4 drakeprovost drakeprovost 4096 Feb 27 19:58 .ros
drwxr-xr-x 11 drakeprovost drakeprovost 4096 Jul 19 22:40 RoverCoreOS
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Feb 13 13:45 .rviz
drwxr-xr-x 3 drakeprovost drakeprovost 4096 Oct 15 2019 snap
drwx------ 2 drakeprovost drakeprovost 4096 Oct 15 2019 .ssh
-rw-r--r-- 1 drakeprovost drakeprovost 0 Oct 15 2019 .sudo_as_admin_successful
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Templates
drwxr-xr-x 2 drakeprovost drakeprovost 4096 Oct 15 2019 Videos
-rw------- 1 drakeprovost drakeprovost 761 Oct 15 2019 .viminfo
lrwxrwxrwx 1 drakeprovost drakeprovost 33 Jul 19 22:40 .vimrc -> /home/drakeprovost/dotfiles/vimrc
drakeprovost@shatterdome:~$ source ~/.bashrc
bash: /home/drakeprovost/.bashrc: No such file or directory
drakeprovost@shatterdome:~$ git clone https://github.com/DrakeProvost/dotfiles.git
Cloning into 'dotfiles'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 42 (delta 21), reused 29 (delta 11), pack-reused 0
Unpacking objects: 100% (42/42), done.
drakeprovost@shatterdome:~$ cd dotfiles
drakeprovost@shatterdome:~/dotfiles$ ./makesymlinks.sh
Creating /home/drakeprovost/dotfiles_old for backup of any existing dotfiles in ~
Moving any existing dotfiles from ~ to /home/drakeprovost/dotfiles_old
Creating symlink to /home/drakeprovost/dotfiles/bash_aliases in ~
Symlink to /home/drakeprovost/dotfiles/bashrc already exists
Creating symlink to /home/drakeprovost/dotfiles/vimrc in ~
To complete the setup, please run the following command:
source ~/.bashrc
drakeprovost@shatterdome:~/dotfiles$ cd
drakeprovost@shatterdome:~$ ls #notice that dotfiles still exists this time
catkin_ws Documents Downloads Pictures snap
catkin_ws_PMCurdf dotfiles examples.desktop Public Templates
Desktop dotfiles_old Music RoverCoreOS Videos
drakeprovost@shatterdome:~$ source ~/.bashrc #this now works like you would expect
drakeprovost@shatterdome:~$
Here's the output in your question annotated:
drakeprovost@shatterdome:~/RoverCoreOS$ git clone https://github.com/DrakeProvost/dotfiles.git
Cloning into 'dotfiles'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 42 (delta 21), reused 29 (delta 11), pack-reused 0
Unpacking objects: 100% (42/42), done.
NOTE: you were in the directory ~/RoverCoreOS
when you ran the above git clone
so the above created the directory ~/RoverCoreOS/dotfiles
, not ~/dotfiles
.
drakeprovost@shatterdome:~/RoverCoreOS$ cd dotfiles/
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ls
bash_aliases bashrc makesymlinks.sh README.md vimrc
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ./makesymlinks.sh
Creating /home/drakeprovost/dotfiles_old for backup of any existing dotfiles in ~
Moving any existing dotfiles from ~ to /home/drakeprovost/dotfiles_old
Creating symlink to /home/drakeprovost/dotfiles/bash_aliases in ~
Creating symlink to /home/drakeprovost/dotfiles/bashrc in ~
Creating symlink to /home/drakeprovost/dotfiles/vimrc in ~
To complete the setup, please run the following command:
source ~/.bashrc
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ ls
bash_aliases bashrc makesymlinks.sh README.md vimrc
All of the above happened in ~/RoverCoreOS/dotfiles
.
drakeprovost@shatterdome:~/RoverCoreOS/dotfiles$ cd
You are now in the directory ~
drakeprovost@shatterdome:~$ ls -al #.bashrc, .vimrc, and .bash_aliases were all red symlinks here, meaning they pointed to non-existent files. Also note that the dotfiles directory has disappeared
~/dotfiles
didn't disappear, it never existed. ~/RoverCoreOS/dotfiles
existed and presumably still exists.
...
drakeprovost@shatterdome:~$ git clone https://github.com/DrakeProvost/dotfiles.git
Cloning into 'dotfiles'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 42 (delta 21), reused 29 (delta 11), pack-reused 0
Unpacking objects: 100% (42/42), done.
Now you've created the directory ~/dotfiles
and from here on things work as you expect.
I'd recommend you modify your script to add some defensive checks. They can't stop you from doing the above but they can at least alert you of some issues and they would have caught the above problem (assuming you didn't have an old dotfiles
directory with the expected files in your HOME dir), e.g.:
[[ -d "$dir" ]] || { ret="$?"; echo "dir "$dir" does not exist"; exit "$ret"; }
for file in $files; do
[[ -s "$dir/$file" ]] || { ret="$?"; echo "file "$dir/$file" does not exist or is empty"; exit "$ret"; }
done
# create dotfiles_old in homedir
echo "Creating $olddir for backup of any existing dotfiles in ~"
mkdir -p "$olddir" || { ret="$?"; echo "Failed to create olddir "$olddir""; exit "$ret"; }
You can add other defensive checks like that as you see fit.
Answered by Ed Morton on November 6, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP