I have been making script that will back up and restore a directory. I want to make it better but I need some help.
At the moment the I have the file being saved as just backup.tgz I did have the date added onto the end but when I ran the restore function the I could only have it look for the backup.tgz and not the backup with the date extension. Is there any way to have it look for the most recent backup? Or even look for the backup given by user input?
I have also tried to add a progress bar and make incremental back ups but had no luck there either if someone could help?
Tar Code
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude=$
DESTIN="/Users/Rory/BackUps"
BACKUP="backup.tgz"
CREATE="/dev /proc /sys /temp /run /mnt /media "
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
echo "************************************************"
echo "********* Backup Menu **************************"
echo "************************************************"
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
sleep 3
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
sleep 2
tar cvpfz $DESTIN/backup.tgz $ROOT $ROOT_EXCLUDE
echo "BACKUP COMPLETE"
sleep 2
clear
echo $LIST
elif [ "$opt" = "RESTORE" ]; then
echo "RESTOTING FILES..."
sleep 2
tar xvpfz $DESTIN/$BACKUP -C /Users/Rory/BackUps
sleep 2
if [[ -e "/proc" ]]; then
echo "$CREATE already exists! "
else
mkdir $CREATE
echo "$CREATE are created! "
fi
echo "RESTORE COMPLETE..."
clear
exit
elif [ "$opt" = "DESTINATION" ]; then
echo "CURRENT DESTINATION: $DESTIN/backup.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
else
clear
echo "BAD INPUT!"
echo "ENTER 1 , 2, 3 or 4.."
echo $LIST
fi
done
Well, in the code snippet you posted, you are only looking for backup.tgz.
If you wanted to pick a specific one, you could modify your script to accept an argument and pick one based on a string you input. Or...if you wanted to do based on "how old", you could sort the backup files by date and allow the user to pick 0th, 1st, 2nd, etc.
One thing you may want to check out is rsync. Rsync can only copy files that have changed.
Plus, you can also enable a progress bar with rsync = )
rsync -avP /source/path/ /dest/path/
Check out the man page for more details man rsync
To enable progress bar on restore, you can untar the file and use rsync in reverse, and then you have progress updates = )
If you want to make this a custom numeric progress bar you'll probably need to do something more complicated than simply taking output from rsync.
Related
I am writing a script that needs to create a file if an argument is passed to he script.
If no argument is passed then it will ask for fileName but it needs to have default permission as -rwx- --- - ---.
I am using this command chmod a=-rwx to remove all the default permissions and then i am using chmod u=+rwx to get the desired permission as stated but it is not working.
Can anyone help please?
#!bin\bash
if [ $#==0 ]; then
echo "Please enter a file name?"
read fileName
if [ -f $fileName ]; then
echo "File already exist! Opening for Editing"
sleep 3
nano $fileName
else
echo "File created with the name $fileName"
echo "Opening $fileName for editing "
sleep 3
echo "#!bin\bash" >$fileName
nano $fileName
fi
elif [ -f $1 ]; then
echo "File already exists with the name $1"
echo "Opening for editing"
sleep 3
nano $1
else
fileName="$1"
chmod a=-rwx $fileName
chmod u=+rwx $fileName
echo "File created with the name $filename"
echo "Opening $fileName for editing "
echo "#!bin\bash" >$fileName
sleep 3
nano $1
fi
Your chmod syntax is incorrect. The operation is either = to set the mode to a specific value, + to add modes, or - to remove modes; you can't combine them with =+ and =-.
You can perform multiple operations on a single file by separating them with ,.
So it should be:
chmod go-rwx,u+rwx "$fileName"
Another problem:
if [ $#==0 ]
should be
if [ $# -eq 0 ]
Use -eq for numeric comparisons, and spaces are needed around operators in shell conditions.
Third problem: You're doing the chmod before you create the file. Put it after
echo "#!/bin/bash" >"$fileName"
Fourth problem: #!bin\bash should be #!/bin/bash.
Finally, remember to quote your variables, in case they contain spaces.
Made a script that requests user's correct password (qwerty) comparing a hash in text file. Referencing the script I then have to make a portfolio of items to choose from in other folders that load upon selecting 1-7 and 8 for exit. Have tried a lot given my comments but cannot get it working. Thanks.
#!/bin/bash
#ReadMe=`cat PasswordCheck.sh`
#echo "$ReadMe"
# https://stackoverflow.com/questions/7427262/how-to-read-a-file-into-a-variable-in-shell
#value=$(<PasswordCheck.sh)
#echo "$value"
bash PasswordCheck.sh
# https://stackoverflow.com/questions/13567947/run-bash-commands-from-txt-file
#read -sp 'PasswordCheck.sh'
Val_A="1. Create a folder"
Val_B="2. Copy a folder"
Val_C="3. Set a password"
Val_D="4. Calculator"
Val_E="5. Create Week Folders"
Val_F="6. Check Filenames"
Val_G="7. Download a File"
Val_H="8. Exit"
#read -sp 'UserPassword : ' Pass_Var
#PwdChk='PasswordCheck.sh'
#if read exit O "PasswordCheck.sh" exit 0 "$SecretHashedPassword"; then
if read "qwerty"; then
echo "1. Create a folder
2. Copy a folder
3. Set a password
4. Calculator
5. Create Week Folders
6. Check Filenames
7. Download a File
8. Exit"
exit 0
else
echo "Goodbye"
exit 1
fi
#case $Val_A in
#9) echo "Create a folder selected";;
#8|pork) echo "IDK...";;
#*) echo "Please select a response from numbers 1-4.";;
#esac
#"2. Copy a folder"
#"3. Set a password"
#exit 0
#https://www.linkedin.com/learning/search?entityType=VIDEO&keywords=bash%20case&u=2072140
#if ["$Val_A" -eq "1"]; then
#bash Foldermaker.sh
#if read "1"; then
#fi
exit 0
The password checking part of your script remains fuzzy to me, however I might be able to help you with the menu question.
Select might be what you need to get the menu of choices set up.
Below is a sceleton script that you can extend according to your needs:
#!/bin/bash
function menu() {
options=("Create_a_folder" "Copy_a_folder" "Set_a_password" "Calculator" "Create_Week_Folders" "Check_Filenames" "Download_a_File" "exit")
echo "Choose option:" 1>&2
select opt in ${options[#]}; do
case ${REPLY} in
*) choice="${options[$(( $REPLY - 1 ))]}"; break;;
esac
done
echo "$choice"
}
#passwordcheck=`somefunction`
passwordcheck=true # replace this once your function is ready
if [ "$passwordcheck" == "true" ]; then
choice=`menu`
[[ "$choice" == "exit" ]] && exit
echo "You have chosen: $choice"
fi
Please if I run the command
# CREATE TRASH FOLDER
if ! [ -d "$HOME/deleted" ] ; then
mkdir $HOME/deleted
fi
TRASH=$HOME/deleted
mv $# $TRASH
To move file or directory to the trash created. what is the possible command i can run to recover same file to the original directory
If you create a deleted directory like this, you will probably get some unexpected behavior. For example:
rm_script test.txt
cd ../other_directory
rm_script test.txt
will create a single file test.txt with the content of the one in other_dir. Even more fun when you start rm_scripting/moving directories.
Knowing this, and referring once more to trash-cli (see comment Aserre), you might:
if ! [ -d "$HOME/deleted" ] ; then
echo "What a pity! No deleted directory."
echo "Your file(s) is/are lost forever!"
exit 361
fi
TRASH=$HOME/deleted
for file in $# ; do
if [ -f "$TRASH/$file" ] ; then
cp "$TRASH/$file" .
else
echo "Hmm,.. I cannot find $file."
fi
done
This also may have some unwanted results, like removing the file from one directory and un-deleting it in another.
I just do the reverse of the same command line
function undo () {
echo -n "Do you want to recover $*? "
read ANSWER
if [ "$ANSWER" = "y" ]; then
mv $TRASH/$# $PWD
echo "$# successfully recovered"
else
echo "Oops, request denied"
fi
}
I am trying to make this script handle file with spaces in them. it is supposed show and execute the content of files in a directory. when I select a file with a space in it, bash fails with bash: foo: no such file or directory, What am I missing to make this handle files correctly
# /etc/skel/.bashrc
#Interactive shell detection
if [[ $- != *i* ]] ; then
# Shell is non-interactive. Be done now!
return
fi
#kv-bash (easy) var database & setup of info
echo "type 'menu' for a bash menu"
#done####################
#to easily launch crouton enviroments
addentry() {
cd ~/.sslm
echo "Name your menu entry."
read entry
sleep 1s
if [ -e "$entry " ]
then
echo "Error, Menu entry already exists"
addentry
else
echo "what do you want the entry to do?"
read entryexec
echo "$entryexec && menu"> ~/.sslm/"$entry"
echo "done"
cd ~/
fi
sleep 1s
}
###################
delentry() {
cd ~/.sslm
ls -x
echo "what entry do you want to delete?"
read del
rm "$del"
echo "the work has been done, he is dead"
}
###################
menu() {
clear
cd ~/.sslm
echo "-- simple shell launcher menu v1.o --"
# set the prompt used by select, replacing "#?"
PS3="Use number to select a file or 'exit' to leave: "
# allow the user to choose a file
select filename in *
do
# leave the loop if the user says 'stop'
if [[ "$REPLY" == exit ]]; then
cd ~/
break
fi
# complain if no file was selected, and loop to ask again
if [[ "$filename" == "" ]]
then
echo "'$REPLY' is not a valid number"
sleep 1s
continue
fi
# now we can use the selected file, trying to get it to run the shell
script
. $filename
# it'll ask for another unless we leave the loop
break
done
}
menu
also, this is on a chromebook, so there is no apt.
At this part:
script
. $filename
I just needed to change to . "$filename"
thx #PesaThe
I have written a script that backs up and restores files. I have a problem in that when the user enters '2' for a restore the program says that this is an invalid input, all other options work fine. I feel it is something small that I have missed but I cant fix it
Update and Restore Script
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude=/backup2.tgz"
DESTIN="/Users/Rory/test/"
BACKUP="backup2.tgz"
CREATE="/dev /proc /sys /temp /run /mnt /media "
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
echo "************************************************"
echo "********* Backup Menu **************************"
echo "************************************************"
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
sleep 3
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
sleep 2
tar cvpfz $DESTIN/backup.`date +%d%m%y_%k:%M`.tgz $ROOT $ROOT_EXCLUDE_DIRS
echo "BACKUP COMPLETE"
sleep 2
exit
elif [ "$opt" = "RESTORE" ]; then
echo "RESTOTING FILES..."
sleep 2
tar xvpfz $BACKUP_FILE -C /
sleep2
echo "RESTORE COMPLETE..."
if [[ -e "/proc" ]]; then
echo "$CREATE_DIRS allready exists! "
else
mkdir $CREATE_DIRS
echo "$CREATE_DIRS are created! "
fi
exit
elif [ "$opt" = "DESTINATION" ]; then
echo "CURRENT DESTINATION: $DEST_DIR/backup.`date +%d/%m/%y_%k:%M`.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $LIST
else
clear
echo "BAD INPUT!"
echo "ENTER 1 , 2, 3 or 4.."
echo $LIST
fi
done
Except where you missed the ending quote where you set ROOT_EXCLUDE (line #4), it looks okay to me. I take it the missing quote is a transcription error or your program wouldn't really work at all.
I've tried out the program and it seems to work.
A debugging trick is to put set -xv to turn on debugging in your script and set +xv to turn it off. The -x means to print out the line before executing, and the -v means to print out the line once the shell interpolates the line.
I'm sure that you'll immediately see the issue once you have set -xv in your program.
As part of this, you can set PS4 to the line prompt to print when the debugging information is printed. I like setting PS4 like this:
export PS4="[\$LINENO]> "
This way, the line prompt prints out the line it's executing which is nice.
In your case, I would put set -xv right before you set OPTIONS and then at the very end of the program. This way, you can see the if comparisons and maybe spot your issue.
export PS4="[\$LINENO]> "
set -xv
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
set +xv
By the way, it's better to use double square brackets like [[ ... ]] for testing rather than the single square brackets like [ ... ]. This has to do with the way the shell interpolates the values in the test.
The [ ... ] is an alias to the built in test command. The shell interpolates the line as is and the entire line is executed.
The [[ ... ]] are a compound statement where the shell will interpolate variables, but not the entire line. The line is kept as whole:
foo="one thing"
bar="another thing"
This will work:
if [ "$foo" = "$bar" ]
then
echo "Foo and bar are the same"
fi
This won't:
if [ $foo = $bar ]
then
echo "Foo and bar are the same"
fi
The shell interpolates the line as is:
if [ one thing = another thing ]
And this is the same as:
if test one thing = another thing
The test command looks at the first item to see if it's a standard test, or assumes three items and the second item is a comparison. In this case, neither is true.
However, this will work:
if [[ $foo = $bar ]] # Quotes aren't needed
then
echo "Foo and bar are the same"
fi
With the [[ ... ]] being a compound command, the $foo and $bar are replaced with their values, but their positions are kept. Thus, the = is recognized as a comparison operator.
Using [[ ... ]] instead of [ ... ] has solved a lot of hard to find shell scripting bugs I have.