Symlink to file which does not exist yet
A rewrite to reduce duplication
#!/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 ...
Notes:
mkdir -p
will create the directory if it does not exist- check that the directory/file is not already a symbolic link first.
- if specific files require specific permissions, no choice but to specify it.
Related videos on Youtube
![LastSecondsToLive](https://i.stack.imgur.com/WKH81.jpg?s=256&g=1)
LastSecondsToLive
Updated on September 18, 2022Comments
-
LastSecondsToLive almost 2 years
I'm currently trying to cleanup my home directory by moving files like
.vimrc
,.bash_profile
, etc. to a directory.dotfiles
in my home directory.The idea is to use symbolic links to these files afterwards:
ln -s ~/.dotfiles/.vimrc ~/.
This works quiet fine, but I'd like to automate this process by writing my first bash script and I ran into some trouble.The script currently looks something like this:
#!//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 ""
As you can see the code is pretty repetitive, but first things first. The code should work roughly like this. Check whether file (for example
init.vim
) exists in my home directory. If it does exists move it to either~/.other
(not so important files) or to~/.dotfiles
(important files). If it doesn't exist create a file (or directory) in~/.dotfiles
or~/.other
. Symlink afterwards.So far the theory. The problem is, if the file does't exist in my home-directory yet - the script just creates a file in
~/.dotfiles
/~/.other
, and links the name in the home directory to it. This doesn't really work out in practice, since some files need specific permissions. For exampleneovim
doesn't recognize some files if they are created with this script and it's not very efficient to just create the files before they are even used.Is there a way to fix this (for example by creating a link, without creating the target file - I tried it once to link
.bash_history
to.other/.bash_history
, the link worked fine, butbash
couldn't write to a non existing file)? It would be optimal if new files would be created in the right place and I only need to specify the right place before?PS: When the file already exists the script works fine (it just moved the file to the new location and links it).
-
LastSecondsToLive over 8 years@glennjackman I do know about the touch command, but how should I know about what permissions I need to set? I'd need to research for every single file. There has to be a more easy way. I thought about aliasing the script to command like
cleanup
and it loops over all files in the home directory and asks the user if he wants to move it to~/.dotfiles
or~./other
, but then the user had to actually do something and had to execute the code multiple times (if knew files are added to the home directory - I can't prevent the creation in the home directory). -
Mat over 8 yearsUnrelated but what's up with the sudo tricks at the start? Doesn't seem like your script needs elevated privs.
-
LastSecondsToLive over 8 years@Mat You are probably right, I just think one time I got
permission denied
, when I tried to create a dir. I'm honestly not sure about it. I should probably remove it. Thanks!
-
-
LastSecondsToLive over 8 yearsHow did you find the needed permission so fast? This is honestly amazing! Thank you so much!
-
Angel Todorov over 8 yearsI did an
ls -la
and noted what perms my files have.