Skip to content

Instantly share code, notes, and snippets.

@Recoskie
Last active December 31, 2023 12:49
Show Gist options
  • Save Recoskie/fda41f4a24bab6fcf8de to your computer and use it in GitHub Desktop.
Save Recoskie/fda41f4a24bab6fcf8de to your computer and use it in GitHub Desktop.
A simple fast easy to use shell script to relocate the user folders to a flash drive or a interal system drive. Works on any linux os.
echo "This script requires administrative privilege to run!"
sudo echo
if ! echo "$password1" | sudo -Sv -p ''; then
exit 1
fi
#
step=0;l=1;DiskN=null;Disk=null;UUID=null;Format=null
#
function Drive-Select
{
#
# Display usage for selecting the Disk drive.
#
if [ "$step" = "0" ]; then clear
echo Use the up, and down arrow keys to select the Drive you want to use for your user folders.
echo Hit [Enter] to select drive. Hit any other key to cancel separate user folder setup.
step=1
#
# Display the partition setup menu if Disk is selected.
#
elif [ "$step" = "2" ]; then clear
echo Select the partition on \"$NDisk\" you want to use for your user folders.
echo Use the up, and down arrow keys to select the partition.
echo Hit [Enter] to select partition. Hit any other key to cancel separate user folder setup.
step=3
fi
#
# If the disk drive is not selected setup disk options in file f using fdisk.
#
if [ "$step" = "1" ]; then sudo fdisk -l > ~/f 2> /dev/null; sed -n '/Disk \//p' ~/f > ~/f2; mv f2 f
#
# If disk is selected Setup each partition on selected disk using blkid write options to file f.
#
elif [ "$step" = "3" ]; then sudo blkid > ~/f; grep "$Disk" ~/f > ~/f2; mv f2 f; fi
#
# Limet selected drive, or partition for number of lines in file f.
#
if ((l < 1)); then ((l = 1)); fi
if ((l >= $(wc -l ~/f | cut -d " " -f 1))); then ((l = $(wc -l ~/f | cut -d " " -f 1))); fi
#
# Display selected line from file f.
# The selected displayed line can be drives if disk is not set, or partitions on the selected disk.
#
echo -ne "\033[2K"$(sed -ne $l'p' ~/f)"\r"
#
# Read key input.
#
read -rsn1 key1; read -rsn1 -t 0.001 key2; read -rsn1 -t 0.001 key3
#
# If arrow key up is hit move the line Selection up one and start over.
if [ "$key1$key2$key3" = $'\033'[A ]; then ((l++)); Drive-Select
#
# If arrow key down is hit move the line Selection down one and start over.
elif [ "$key1$key2$key3" = $'\033'[B ]; then ((l--)); Drive-Select
#
# If the enter key is hit.
elif [ ${#key3} -eq 0 ]; then
# Set the disk drive to the selected disk If disk is not set.
if [ "$step" = "1" ]; then
NDisk=$(sed -ne $l'p' ~/f) #Get the Disk drive name.
echo $NDisk | grep -o -P '(?<=Disk ).*(?=:)' > ~/Drive #Fiter the selected disk path.
Disk=$(<~/Drive) #Set the Selected disk drive path.
rm ~/Drive; step=2; Drive-Select # start over with partition selection.
# Set Selected partition from blkid.
elif [ "$step" = "3" ]; then
step=4;Part=$(sed -ne $l'p' ~/f) #get selected line from file f.
UUID=$(echo $Part | grep -o -P '(?<=UUID=").*(?=" )') #Get the UUID.
Format=$(echo $Part | grep -o -P '(?<=TYPE=").*(?=")') #Get partition format.
fi
fi
#
rm ~/f 2> /dev/null # End of function remove file f.
#
}
#
# User folder setup.
#
function FSTAB_Setup
{
#
# Ask user if they would like to store there user folder documents on a different drive.
#
clear
echo Would you like to Store your documents, and files on a separate drive.
read -p "Hit y on the keyboard for yes, or n for no" -n 1 -r
echo
#
if [[ $REPLY =~ ^[Yy]$ ]]; then
#
# First Remount everything from FSTAB which sets up the systems mount points on boot.
#
sudo mount -a 2> ~/err
#
# If FSTAB has errors prompt the user to fix the errors.
#
if [ -s ~/err ]; then clear
echo Errors In FSTAB had ben found in order to setup user folders FSTAB has to be Repaired.
read -p "Remove FSTAB Errors? (Hit y on the keyboard for yes, or n for no)" -n 1
echo
#
# Read though each error and remove the lines that are producing the errors.
#
if [[ $REPLY =~ ^[Yy]$ ]]; then touch ~/rml
while read errs; do errs=$(echo $errs | grep -o -P '(?<=line ).*(?= in /etc/fstab)')
echo $(sed -ne $errs'p' /etc/fstab) >> ~/rml; done < ~/err;
if [ -s ~/rml ]; then grep -v -f ~/rml /etc/fstab > ~/FSTAB; sudo mv ~/FSTAB /etc/fstab; fi; rm ~/rml;
#
# If user does not want to remove erros.
#
else rm ~/err;
echo Unable to setup user folders with fstab errors.
read -p "press any key to start setup over." -n 1
FSTAB_Setup; exit 1
fi
fi; rm ~/err
#
# Ask the system for all mount points That locate to the user folders store the output into file MPoints.
# These can be system mount points from FSTAB, or mount commands that have been done to user folders.
#
mount | grep -ER "$HOME" > ~/MPoints
#
# Remove gvfs fuse daemon Which Is part of the Linux system, however it is in user folder path, but is hidden.
#
grep -v "gvfs-fuse-daemon" ~/MPoints > ~/MPoints2
#
# Flip Mount points backwards.
# If more than one folder is mounted to the same folder the last mount point has to be removed first.
#
tac ~/MPoints2 > ~/MPoints; sudo rm ~/MPoints2
#
# Check if there are any user folder mount points in file MPoints.
#
if [ -s ~/MPoints ]; then
#
# Ask User if they want to unmount and restore the user folders to default settings if there are mounted points.
#
clear
echo User folders are already configured you first have to restore user folders to system default locations.
read -p "Restore to default? (Hit y on the keyboard for yes, or n for no)" -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
#
# The file drives will be used to store all drives mounted to each user folder except the root file system drive.
# This is used for targeting and removing the drive mount lines in FSTAB.
#
touch ~/Drives
#
# Read though the mounted user folder points.
#
while read p; do
#
# Get the user folder mount directory.
#
p=$(echo $p | grep -o -P '(?='$HOME').*(?= type)')
#
# Ask the file system which disk is mounted to the user folder then store result in a temporary file.
#
df $p > ~/temp 2> /dev/null
#
# Unmount the user folder so it is no longer connected to a different location.
#
sudo umount -lf $p
#
# Load the temporary file and Filter The disk that the folder located too.
#
p=/$(echo $(sed -ne 2p ~/temp) | grep -o -P '(?<= /).*(?=)')
#
# Store mounted drives into a file called drives only if it is not in file drives.
# Skip the root drive in case it was mounted into a folder so we do not remove the system disk instead we only unount the folder.
#
if ! [ "$p" = "/" ]; then grep -q "$p" ~/Drives || echo "$p" >> ~/Drives; fi
#
done < ~/MPoints; sudo rm ~/temp
#
# Unmount each disk that was connected to the user folders.
#
while read p; do sudo umount -lf $p; done < ~/Drives;
#
# Now backup FSTAB in case fails.
#
sudo cp /etc/fstab ~/Backup
#
# Read all mount lines in fstab that go to the user folders. Store them into file MPoints.
#
grep -ER "$HOME" "/etc/fstab" > ~/MPoints
#
# Remove all disk drives that were mounted to user folder from fstab.
#
grep -v -f ~/Drives /etc/fstab > ~/FSTAB
#
# Remove User folder mount points.
#
grep -v -f ~/MPoints ~/FSTAB > ~/FSTAB2
#
# Also remove commented lines my code generates when it sets up user folder mount points.
#
grep -vwE "(#Mount disk for user folders.|#bind mount the Linux folder paths to disk.)" ~/FSTAB2 > ~/FSTAB; sudo rm ~/FSTAB2
#
# Now cleanup and Remove MPoints file, and Drives file.
#
sudo rm ~/Drives ~/MPoints
#
# setup FSTAB
#
sudo mv ~/FSTAB /etc/fstab
#
# reload and test FSTAB
#
sudo mount -a 2> ~/err
#
# Check if restore failed if so put FSTAB back the way it was.
#
if [ -s ~/err ]; then sudo rm ~/err; sudo mv ~/Backup /etc/fstab
echo Restore failed Unable to do user folder setup.
read -p "press any key to start setup over." -n 1
FSTAB_Setup; exit 1
#
# If user folders are restored successfully restart setup.
#
else sudo rm ~/err ~/Backup
echo User folders have been restored successfully.
read -p "press any key to start setup over." -n 1
FSTAB_Setup; exit 1
fi
fi
#
# If user folders are not configured then this is run.
#
else
#
# Remove user folders mount points check.
#
sudo rm ~/MPoints
#
# Start my Disk Select setup code.
#
step=0; Drive-Select
#
# Check if user finished selecting a disk partition.
#
if [ "$step" = "4" ]; then
#
# Unmount the disk in case it is mounted.
#
sudo umount -lf $DISK; clear
#
# Display disk info.
#
echo Selected Disk drive is "$NDisk"
echo Selected Partition is "$UUID"
echo Disk Partition format "$Format"
#
# Check If selected drive is a system partition.
#
if grep -q $UUID "/etc/fstab"; then
echo The selected disk can not be used because the partition is used by your system.
read -p "Please use a different partition stating setup over hit any key to continue" -n 1
FSTAB_Setup; exit 1
fi
#
# Backup FSTAB.
#
sudo cp /etc/fstab ~/Backup
#
# Make the folder path in folder media so the drive can be mounted to the file path.
#
sudo mkdir -p /media/Files
#
# Add Disk drive mount line to fstab.
#
echo "#Mount disk for user folders." | sudo tee -a /etc/fstab > /dev/null
echo "UUID=$UUID /media/Files $Format defaults 0 0" | sudo tee -a /etc/fstab > /dev/null
#
# Test if Drive mounted successfully to path media then folder files.
# If it failed put FSTAB back the way it was.
#
sudo mount -a 2> ~/err; if [ -s err ]; then sudo mv ~/Backup /etc/fstab; sudo rm ~/err
echo "ERROR Drive failed to load. You can try aging or chose a different drive starting over."
read -p "Press Any key start setup over."; FSTAB_Setup; exit 1
fi
#
# Create the user folders on both mount paths if they are not already existent.
#
i=0; declare -a Folders=("Desktop" "Documents" "Pictures" "Music" "Videos" "Downloads" "Public" "Templates")
sudo mkdir -p ~/{Desktop,Documents,Pictures,Music,Videos,Downloads,Public,Templates};
sudo mkdir -p /media/Files/{Desktop,Documents,Pictures,Music,Videos,Downloads,Public,Templates}
#
# bind mount the user folders to drive.
#
echo -n "#bind mount the Linux folder paths to disk." | sudo tee -a /etc/fstab > /dev/null
echo -e "\r\n/media/Files/"{Desktop,Documents,Pictures,Music,Videos,Downloads,Public,Templates}" $HOME/"${Folders[((i++))]}" none bind 0 0" | sudo tee -a /etc/fstab > /dev/null
#
# Now the only way that FSTAB can fail locating to the folders on the disk is that the partition type is not
# Designed for storing files, or the partitions file array list is bad, or sectors are bad and the next possible address is being used to store the folder paths.
#
# Load FSTAB which now locates directly to the user folders on the selected drive. Display the drive partition is bad if any errors.
# If it failed put FSTAB back the way it was.
#
sudo mount -a 2> ~/err; if [ -s err ]; then sudo mv ~/Backup /etc/fstab; sudo rm ~/err
echo "ERROR The Disk Can not be read or wrote too. You can try aging or chose a different drive starting over."
read -p "Press any key to start setup over." -n 1; FSTAB_Setup; exit 1
fi
#
# If this is reached the setup is successful.
#
echo User folders have been configured successfully.
read -p "Press Any key to exit setup." -n 1;
echo
#
# Cleanup remove fstab backup and errors file.
#
sudo rm ~/Backup ~/err
#
# If user does not complete the disk drive selection.
#
else
echo Custom user folder setup Canceled.
fi
fi
#
# If user canceled setup.
#
else
echo Custom user folder setup Canceled.
fi
}
#
#Start FSTAB setup.
#
FSTAB_Setup
#
@Recoskie
Copy link
Author

This script is safe to run even if the user folders are already mounted, and fstab has been configured manually.

(1) This script can repair fstab errors basically remove any mount lines you may have added to fstab that are broken.

(2) Then this script lets you remove any mount points, and fstab configurations done to your user folders without modifying any other mount points in fstab.

(3) This script also lets you configure which disk you would like to store your user folders on.

(4) During relocating the user folders the code will reload fstab, and the file system during each step if any error occurs a message is displayed for what the problem is and then fstab is put back the way it was.

(5) This script can be run as many times as you like to restore the user folders to there system default locations, or to change them to a selected disk and partition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment