Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
#!/bin/bash
#
# Partial Rsync File Restore Script
#
#
clear
echo
# Shell loads into /raid0/data/backup/bin/
cd .. # I cd to the backup directory here
cd store/ # Then cd into store/ here, which is where the script should run
echo "You are here> `pwd`"
echo
echo "Please select a directory or file to restore"
echo
select file in `for i in $(ls); do echo ${i%%.*}; done`
do
echo; echo "$file"
break;
done
if [ -d "$file" ]
then
cd $file; pwd
else
echo "Restore $file?"
fi
unset file
select file in `ls`; do echo "$file"; break; done
if [ -d "$file" ]
then
cd $file
else
echo "Restore $file?"
fi
unset file
select file in `ls`; do echo "$file"; break; done
if [ -d "$file" ]
then
cd $file
else
echo "Restore $file?"
fi
unset file
The problem I am having is with the select and if commands. Can I create some kind of loop to accomplish this without having to recreate the code manually everytime.
Can I create some kind of loop to accomplish this without having to recreate the code manually everytime.
If you put your selection menu in a function:
Code:
doSomething() { select SELECTION in $(find $PWD -maxdepth 1 -printf "\"%f\"\n"); do doSomethingElse; done; }
then each time the function is executed it will refresh the selection list. If you put your file ops in a function too:
Code:
doSomethingElse() { if [ -d "${SELECTION}" ]; then cd "${SELECTION}" && doSomething
elif [ -f "${SELECTION}" ]; then echo "Restore $file? [y/N]"; else cd .. || doSomething; fi; }
then having the first function execute the second one and vice versa you'll create a loop that always does something. (Start by executing the doSomething function)
* Note 0) due how to "select" works in your code as well as in this example the 'find' and 'ls' commands return IFS-unsafe results, resulting in multiple menu entries for what are single items, also note 1) your menu doesn't distinguish directory names (to enter) from file names and 2) your approach may work well with a single directory holding 2 or 3 files but not with a directory holding 100 directories and 1 file or 2000 directories plus subdirectories.
@unSpawn, I still haven't found a way around using 'ls' or 'find'. I know that they return unsafe IFS results and that it results in some files having multiple menu entries. I am still looking for a way to combat that issue. However, I have improvised my code and would like to have you look at it for me. Below you will see my new code. Please note that I have additional problems that I now need to resolve. I am hoping that you can help me with these. I will explain them below. Please also note that the script is still incomplete.
Thanks
Code:
#!/bin/bash
#=========================================================================================================
# Rsync File Restore Script [Unfinished] ********************************************* #
# This script is in /raid0/data/backup/ * * #
# * Author: Johnny J. Davis * #
# * Date Created: * #
# [ Last Modified ] * Script name: filerestore_take2.sh * #
# Date: 12/18/12 * [incomplete] * #
# Time: 9:32 AM * * #
# ********************************************* #
##########################################################################################################
#=========================================================================================================
# ****[Begin Variables]****
#=========================================================================================================
LogDns1=/raid0/data/backup/logs/dns1_file_restore.log
LogServices=/raid0/data/backup/logs/services_file_restore.log
LogInet1=/raid0/data/backup/logs/inet1_file_restore.log
LogUser=/raid0/data/backup/logs/UserLog.log
NoLog="echo No log present for $secondhalf" # The variable $secondhalf will be assigned later
RSYNC=/usr/bin/rsync # on as a result of user input.
DATE=/bin/date
ECHO=/bin/echo
USER=root
#---------------------------------------------------------------------------------------------------------
# {End Variables}
#=========================================================================================================
# ****[Begin Functions]****
#=========================================================================================================
# Function to remove previous log, if present (DNS1)
removeLogDns1(){
if [ -a $LogDns1 ]
then
rm $LogDns1
else
echo "No log present for Dns1!"
fi
}
# Function to remove previous log, if present (SERVICES)
removeLogServices(){
if [ -a $LogServices ]
then
rm $LogServices
else
echo "No log present for Services!"
fi
}
# Function to remove previous log, if present (INET1)
removeLogInet1(){
if [ -a $LogInet1 ]
then
rm $LogInet1
else
echo "No log present for Inet1!"
fi
}
#-------------------------------------------------------------(Step 6)------------------------------------
# Function that confirms the intention to restore and restores the file
# placed in the variable fileName by the fileCheck function in step 3.
restoreFile(){
echo -n "Restore $fileName? [Y/N]?> "
read -r answer
case $answer in
Y ) echo "Restoring the file $fileName!" # Will be Adding additional commands here
;;
N ) echo "Action aborted, nothing restored!"; makeSelection
;;
* ) echo "Must answer with a Y or N!"
;;
esac
#exit 0; sh /raid0/data/backup/filerestore_take2.sh
}
#-------------------------------------------------------------(Step 5a)---------------------------
# Function that changes the current working directory to the choice made in step 2, if infact
# it was a directory.
cdNow(){
if [ -d $choice ]
then
cd $choice; echo "Changed Directory to $PWD"; makeSelection
else # If the choice from step 2 is not a directory and
echo "This is not a directory!" # manages to make it to this step, the script will
fi # terminate with echo.
}
#-------------------------------------------------------------(Step 5b)---------------------------
# Function checks to see if the choice from step 2, is infact a file. If so, it stores the file
# name in a variable called fileName and proceeds to call the restoreFile function in step 4.
fileCheck(){
if [ -f $choice ]
then
fileName=$choice; restoreFile
else # If the choice from step 2 is not a file
echo "This is not a file!" # and manages to make it to this step, the
fi # script will terminate with echo.
}
#-----------------------------------------------------------(Step 4)--------------------------------------
# Function that determines if the selection from step 1 is a file
# or directory and moves to next function based on the result.
checkType(){
while [ -d $choice ] # Checks the variable to see if it is a directory.
do # If so, it calls the cdNow function, in step 5a.
cdNow
break;
done
while [ -f $choice ] # Checks the variable to see if it is a file. If so,
do # it calls the fileCheck function, in step 5b.
fileCheck
break;
done
}
#------------------------------------------------------------(Step 3)-------------------------------------
# Function checks for existance of files.
anyFiles(){
ls ./* > /dev/null 2>&1
if [ "$?" = "0" ]
then
checkType
else
echo "No files exist here!"
fi
}
#------------------------------------------------------------(Step 2)-------------------------------------
# Fuction that allows selecting either a file or directory.
makeSelection(){
PS3="Enter choice [ctrl-c quits]> "
select choice in `for i in $(ls -X); do echo ${i%%.*}; done`
do echo; break; done
anyFiles
}
#---------------------------------------------------------------------------------------------------------
# {End Functions}
#=========================================================================================================
# ****[Script Start]**** (Step 1)
#=========================================================================================================
#
echo
echo
echo
clear
echo "Current Working Directory: $PWD"
echo
echo "Please select file or directory."
echo
echo "[Selecton Menu]"
makeSelection
Upon execution of the script, I get some prompts duplicated after performing the task. For instance, after traversing several directories, to finally reach the file that I would like to restore. I am prompted to restore the file. I say yes to restore. I get the echo stating that the file is being restored, then immediately after, I get the same prompt. I know it's something in the functions causing this, but I don't know how to resolve it. Also, while entering a selection at the selection menu, I deliberately entered an invalid choice to see what would happen. It drops to /root and echos "No files exist here!" and prompts to Restore ? [Y/N]?>. I don't know what's causing this or how to fix it. Do you have any ideas about any of this?
I should also point out that I am working on a Thecus N4100Pro Nas via ssh. The box has a very limited command set, as it is running a dumbed-down version of Slackware. Some options for the commands that do exist, are non-existent on this box. For instance, 'find' with the -maxdepth or -mindepth options. Find is a valid command for the box, but the options do not exist.
I still haven't found a way around using 'ls' or 'find'. (..) Upon execution of the script, I get some prompts duplicated after performing the task. For instance, after traversing several directories, to finally reach the file that I would like to restore. I am prompted to restore the file. I say yes to restore. I get the echo stating that the file is being restored, then immediately after, I get the same prompt. I know it's something in the functions causing this, but I don't know how to resolve it. Also, while entering a selection at the selection menu, I deliberately entered an invalid choice to see what would happen. It drops to /root and echos "No files exist here!" and prompts to Restore ? [Y/N]?>. I don't know what's causing this or how to fix it. Do you have any ideas about any of this?
The easiest way to trace shell script problems is to enable verbose / debug mode with a "#!/bin/bash -vx" hashbang or setting "set -vx" below the shebang line. Then run the script piping stderr + stdout through 'tee' to a log file, and perform one task only, for example selecting a non-existent file to restore, and then exit the script. Then read back the log file to see what variables get assigned (or not) and what functions get called and in what order. Tedious to some it gives you the level of insight you need to fix this. Try it and if you've got questions attach your log file as plain text. Wrt the NAS it would be interesting to know if it actually runs slackware user land (and what BASH version) or Busybox. In case of the latter I suggest you install a copy of the Heirloom Shell (@Sourceforge IIRC) which I use for Bourne-compatible scripting.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.