Despite my best efforts, people will misuse this script. Mainly because they probably won’t slow down to read everything in this post. I’ve had done everything I can for people to second-guess, double-check and confirm actions before committing, but this isn’t for complete newbies.
Please read before you inadvertently destroy your filesystem.
I’m not being dramatic, I’m serious.
I’ve written countless times about how to symbolically link or configure XDG directories for creating filesystems which utilize the existing directories generated by Microsoft Windows or at another persistent, at-boot mountpoint defined in /etc/fstab
for creating a dual-boot environment which doesn’t bog down the user with redundancy and duplicate directories / files, but I understand how difficult it may be for some who aren’t familiar with the concept to perform such actions.
With this understanding, I’ve developed a basic script with a menu. Because I wish not to cause any concern for malicius software, I am going to initially share this script here for @moderators to observe, check and vallidate it is clean code and good for the community before I create a file in my GitHub for other people to see, and also to accept input by people who know scripting better than I do. A lot of this came from examples and discussions online, which was effectively my crash course for Bash.
This is also the first time I made a good choice menu in Bash. Once I had a basic understanding and found enough generated examples I was able to create this script which has very few provisions to prevent users from screwing up. So here’s the script…
# Migration script for transferring contents from an existing Linux home directory to mounted shared partition
#
# Intended for people who dual-boot, the partition where personal effects will be shared between Linux and Windows
# should be configured in 'gnome-disks' or manually by editing 'admin:///etc/fstab' before using this script.
read_me='You should not be using this yet.'
no_really='Pick \e[1moption 3\e[0m and modify me.'
# Once finished, you can disable deug output by commenting line 126, like this.
# Don't forget to read notes before proceeding to edit this file!
#=== VARIABLES ===#
# Adjust these as necessary. DO NOT execute this script without adjusting them.
nixPart=$read_me
newPart=$no_really
# For these variables, see note 3.
oldUser=$USER
oldPath=$nixPart/$oldUser
newUser=$USER
newPath=$newPart/$newUser
# Copy behaviour, see note 4.
# copyAction='cp -iR'
#=== NOTES ===#
# 1: This is the directory path to your personal effects in Linux, sans user. Typically this is
###| /home but it should be changed per your system.
#¯¯
# 2: This is the directory path to your personal effects in WIndows, sans user. Typically this is
###| [Windows OS filesystem mountpoint]/Users but it should be changed per your system.
#¯¯
# 3: $USER assumes both mount points will lead to the same directory if using the same output as
###| 'echo $USER' for each. If not, change the user directories for Windows and Linux.
###|
###| due to Microsoft's internet synchronization features your account name may be using your
###| Microsoft account username, truncated to the fifth letter so it will most certainly be
###| different if you used Microsoft credentials and have your Linux username be as you desire.
###|
###| If you use a shared partition instead, BLANK $newUser and $newPart ('') to define $newPath
###| by hand so it refers to the mountpoint where all of your personal effects will be.
#¯¯
# 4: Change the command above to the following if no interaction is desired. (Incl. recursive cp.)
###| 'cp -R': Overwrite if duplicate exists
###| 'cp -nR': Do nothing if duplicate exists
#¯¯
# 5: All mountpoints MUST be configured before using this script. As to be expected since you
###| have to define these paths in the variables above anyway.
#¯¯
### END USER CONFIGURATION SECTION ###
#=== DEBUG ===#
shDbg() {
echo -e DEBUG: Variable output shown
echo -e User 1.... $oldUser
echo -e User 2.... $newUser
echo -e Linux..... $nixPart
echo -e Windows... $newPart
echo -e Old dir... $oldPath
echo -e New dir... $newPath
echo ""
}
#=== PREPARATION ===#
doXfer() {
# Prompt menu for action
echo -e
echo -e "Before continuing, there are multiple ways to handle duplicates."
echo -e "If such exist in $oldPath exist during transfer,"
echo ""
echo -e "what should this script do?"
echo -e "---------------------------"
PS3="Action to take: "
select cpAction in "Ask for each instance" "Overwrite duplicates" "Ignore duplicates"
do
case $cpAction in
"Ask for each instance")
copyAction='cp -iR'
echo -e "You will be asked for each file."
read -p "$pak $nextTask"
break
;;
"Overwrite duplicates")
copyAction='cp -R'
echo -e "All duplicates in $newPath will be destoryed."
read -p "$pak $nextTask"
break
;;
"Ignore duplicates")
copyAction='cp -nR'
echo -e "All duplicates in $newPath will be preserved."
read -p "$pak $nextTask"
break
esac
done
# Copy from Linux directories existing files
$copyAction $oldPath/Documents/* $newPath/Documents
$copyAction $oldPath/Downloads/* $newPath/Downloads
$copyAction $oldPath/Music/* $newPath/Music
$copyAction $oldPath/Pictures/* $newPath/Pictures
$copyAction $oldPath/Videos/* $newPath/Videos
}
#=== SYMBOLIC LINKS ===#
doLinks() {
### This process will replace original directories with linkx, but without losing any files there might have been made.
# Define symbolic links
ln -s $newPath/Documents $oldPath/Documents
ln -s $newPath/Downloads $oldPath/Downloads
ln -s $newPath/Music $oldPath/Music
ln -s $newPath/Pictures $oldPath/Pictures
ln -s $newPath/Videos $oldPath/Videos
}
#=== XDG UPDATE ===#
doXDG() {
### This process will delete original directories, but without losing any files there might have been made.
# xdg1: Define XDG paths
xdg-user-dirs-update --set DOCUMENTS $newPath/Documents
xdg-user-dirs-update --set DOWNLOAD $newPath/Downloads
xdg-user-dirs-update --set MUSIC $newPath/Music
xdg-user-dirs-update --set PICTURES $newPath/Pictures
xdg-user-dirs-update --set VIDEOS $newPath/Videos
}
#=== CLEANUP ===#
doRm() {
rm -rf $oldPath/Documents $oldPath/Downloads $oldPath/Music $oldPath/Pictures $oldPath/Videos
}
#=== MESSAGE TEXT ===#
intro() {
echo -e "Greetings $USER on machine $HOSTNAME. This script will — in one of"
echo -e "two ways — transfer contents from your current system instance to"
echo -e "a location defined by you."
echo ""
echo -e "Prior to making a selection, you should already have this script"
echo -e "configured to use paths you had specified. If you had not opened"
echo -e "this document to modify it yet, pick \e[1moption 3\e[0m and use"
echo -e "your text editor to make necessary changes."
echo ""
echo -e "Select an action below:"
echo -e "-----------------------"
}
msg1() {
echo ""
echo -e "The next series of actions will perform as follows"
echo -e "\e[3mon your behalf\e[0m:"
echo ""
echo -e "- Copy files from the \"big five\" directories in"
echo -e "$oldPath to $newPath"
}
msg2() {
echo ""
echo -e "If you accept these actions, press any key,"
read -p "If you deny these actions, perform ^C now."
}
# Canned lines
pak="Press any key to"
nextTask="continue or ^C to cancel."
#=== MENU ===#
shDbg
intro
PS3="Selection: "
select action in "Make links to new location" "Use XDG for new location" "Do nothing"
do
case $action in
"Make links to new location")
msg1
echo -e "- Delete redundant directories from $oldPath"
echo -e "- Create symbolic links from $oldPath to $newPath"
msg2
doXfer
doRm
doLinks
echo ""
read -p "Finished! $pak exit."
exit
;;
"Use XDG for new location")
msg1
echo -e "- Redefine XDG paths so they go to $newPath"
echo -e "- Delete redundant directories from $oldPath"
msg2
doXfer
doXDG
doRm
echo ""
read -p "Finsihed! $pak exit."
exit
;;
"Do nothing")
read -p "Nothing has been done. $pak exit."
exit
esac
done
…And an explanation of specific script features.
Functions
doXfer
Copies from $oldPath
(in Linux filesystem) to $newPath
(Windows filesystem / shared filesystem). This is before directories in $oldPath
are destroyed, so this should generally go quickly for people who are just starting to dual-boot between WIndows and Manjaro.
The new version of this script wiill also prompt for action and define what become $copyAction
.
doRm
Deletes directories in $oldPath
. Executes after doXfer
.
doLinks
Makes symbolic links from $newPath
to $oldPath
.
doXDG
Reconfigures XDG using xdg-user-dirs-update
. Through that, it changes what is defined in $HOME/.config/xdg-user-dirs.dirs
so if you’d like, back that up before changes are made.
shDbg
Commented in line 124. Remove hashtag to enable a “Debug” feature which lists paths prior to the introduction.
intro
, msg1
, msg2
Flavour text. Reduces redundancy by recycling echoes.
Variables
$oldPart
User-defined location for path to Linux system. Typically this is $HOME
.
$newPart
Path to Microsoft Windows. Usually at NTFS / exFAT mountpoint for Widows in Users/
.
Can also be path to other partition used to save personal effects, but ti assumes the paths already exist.
$oldUser
Name of user in Linux. Usually this would be $USER
.
$newUser
Name of user in Windows. Usually this doesn’t match, so it must be defined by hand. If it does however (or if you used the same name for $USER
as shown when invoking explorer
with %userprofile%
/ as seen in Users/
) then logically this wold be $USER
also.
$oldPath
$oldPart/$oldUser
$oldPath
$newPart/$newUser
$copyAction
Defined in doXfer
. Will either do interactive, clobber or no-clobber.
Script use
Change variables to represent paths in Linux and Wndows filesystems / shared mountpoint and execute. Script will not function unless $oldUser
and $newUser
is defined.
In short this script will create links or redefine XDG paths for Documents
, Downloads
, Music
, Pictures
and Videos
so that copies in a new location are made accessible in the Linux filesystem. Make sure you edit /etc/fstab
by hand or through gnome-disks
so that whatever $newPath
is will be mounted at startup prior to execution so issues with non-existant directories are avoided.
Debug mode is automatically enabled for this revision.
I had tested this script in an isolated directory environment multiple times to make sure the script performs as intended. Please take considerable time making sure everything is correct.
For this revision I also made it generic, so there is no reference to Microsoft Windows beyond what might be in notes.