LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Restore bash script (https://www.linuxquestions.org/questions/linux-newbie-8/restore-bash-script-4175482251/)

gasric 10-26-2013 06:15 AM

Restore bash script
 
Hi im wondering why this script pumps out the error message : move cannot stat `(file being moved)`: no such file or directory

Here's the code im using:
Code:

if [ $1 ]
grep $1 ~/fp.txt #fp.txt stores the full file paths
restore=`grep $1 ~fp.txt`
mv ~/dustbin/ "$1" "restore" && . ~/fp.txt
fi

I'm not a programmer but am slowly learning when I can so excuse the bad programming practices.

grail 10-26-2013 06:44 AM

I see several issues:

1. No then keyword for if

2. I would hazard a guess that the space between ~/dustbin/ and "$1" would be a bit of an issue.

3. The following will rename everything to the string "restore" in the current directory:
Code:

mv ~/dustbin/ "$1" "restore"
4. What is the point of sourcing fp.txt??

gasric 10-26-2013 07:06 AM

Hi sorry i have just read my post and have not really explain it very well!

Here's a better try:

I'm trying to create a restore script that restore any deleted files from the dustbin directory. here is a new code layout I think is better but still pumps out an error, could you point out whats wrong with my code and error please?

Code:

#!/bin/sh
set -xv
if [ "$1" ]
then cd ~/dustbin
restore= grep $1 ~/fp.txt
filename= basename "$restore"
mv $1 $filename "$location1" $location
fi

different from my first post

error:
Quote:

+ `[` test `]`
+ cd /root/dustbin
+ restore=
+ grep test /root/fp.txt
./scripts/test
+ filename=
+ basename ''

+ mv test ''
mv: cannot move `test` to `': bo such file or directory
fp.txt is the text file that stores all full paths of deleted files

Am i missing code?
Is the $location correct?

thanks for your time anyway! :)

grail 10-26-2013 08:19 AM

Have a close look at your output ... you have not used any back ticks to do your process substitution, hence all variables are blank

gasric 10-26-2013 09:30 AM

I'm not very good at this but i think what your trying to say is there are no results happening for restore, filename and basename.

Sorry but if you could give me a few more pointers that would be great?

gasric 10-26-2013 11:29 AM

Only changed a few things... removed whitespace and added back ticks.

Code:

#!/bin/sh
set -xv
if [ "$1" ]
then cd ~/dustbin
restore=`grep $1 ~/fp.txt`
location1=`grep $1 ~/fp.txt $location`
filename=`basename "$restore"`
mv $1 $filename "$location1" $location
fi

New error:
+ `[` alpha `]`
+ cd /root/dustbin
grep $1 ~/fp.txt
++ grep alpha /root/fp.txt
+ location1=` ./alpha
./alpha`
basename "$restore"
++ basename `./alpha
./alpha
+ filename=alpha
+ mv alpha alpha `./alpha
./alpha
mv: target /alpha` is not a directory

So they are returning the information thats needed i think but is it thinking that im trying to restore a directory, not really sure.

Right this is what it says in the file called fp.txt

./alpha

So what im thinking here is that when i delete the file, its storing the file path incorrectly in the fp.txt.
Here is the code i use to delete the files:

Code:

if [ -f $1 ]
file=`basename $1`
then echo `find -name $file` >> ~/fp.txt && mv $1 ~/dustbin && echo "$1 Moved" || echo "File does not exist"
fi

Or am i doing something simple that i cant see?

michaelk 10-26-2013 11:41 AM

Quote:

mv $1 $filename "$location1" $location
Not sure what you are trying to accomplish.

If your file is stored in ~/dustbin then I assume what you want is:
mv "~/dustbin/$1" "$restore"

grail 10-26-2013 11:44 AM

Well I see a few problems with the remove as well, so we will look at it first:

1. You call basename on the file name passed in, is this in case they use the path to the file as well as just the file name on its own?

2. echo not required as the output from find can be directly redirected into the file

3. you call find to be run from wherever you are ... what if you are at the root top level?? This means it will find all (assuming you have access, note you do not have any provision for if you do not)
copies with the same name and echo them to fp.txt ... is this really what you want? can you guarantee that every single file on your system has a unique name??

4. you move the file as it was named and passed to your script, but above we assume the user could pick a random file name so you may not be in the directory where the file is ... this will cause an error

Back to restore script, maybe you can tell me what you think the following line would do?
Code:

mv $1 $filename "$location1" $location
If we imagine we are on the command line and we issued a mv command with 4 arguments, what happens?

PTrenholme 10-26-2013 01:30 PM

Well, the find command requires a root directory, and you have not specified one.
Try find $HOME -name $file

But what's the point of the find command? Before you invoked it, you already knew the $1 was a file, and that it existed, so what you want is, probably, something like this:
Code:

#!/bin/bash
if [ $# -eq 0 -o "${1}" == "-h" -o "${1}" == "--help" ]
then
  cat <<EOF
$0: Move files into the dustbin

Usage: dustbin file1 [file2 ...]

EOF
  exit 0
fi
# Sanity check: Does ~/dustbin exist as a directory?
if [ -e ~/dustbin ]
then
  if [ ! -d ~/dustbin ]
  then
    echo ~/dustbin exists, but it is NOT a directory. >&2
    exit 1
  fi
else
  mkdir -p ~/dustbin
  [ $? -ne 0 ] && exit 2
fi
# Process the arguments
while [ -n "${1}" ]
do
  if [ -f "${1}" ];then
  file="$(basename ${1})"
  path="$(dirname ${1})/$(basename ${1})"
  if [ $(mv "${1}" "${HOME}/dustbin/" 2>/tmp/error) ]
  then
    error="$(cat /tmp/error)"
    rm -f /tmp/error
    printf "ERROR: Could not move \"%s\" into the dustbin.\nmv error\n  $s\n\n" "${path}" "${error}"
  else
    printf "%s\n" "${path}" >> ${HOME}/fp.txt
    printf "\"%s\" has been moved into the dustbin.\n" "${file}"
  fi
  else
    if [ -e "$1" ]
    then
      printf "\"%s\" is not a file. It is %s\n" "${1}" "$(file ${1})"
    else
      printf "\"%s\" does not exist.\n" "$1"
    fi
  fi
  shift
done

Example:
Code:

$ ls          # Current directory contents
dustbin  try2
$ rm ~/dustbin              # Removing the ~/dustbin file to test the creation part
$ ./dustbin  indirect* try2 # Run the script
"indirect*" does not exist.
"try2" has been moved into the dustbin.
$ ls                        # To show it worked
dustbin
$ ls ~/dustbin/            # ...
try2
$

Notes:
  1. The fl.txt file is, I believe, redundant since ls ~/dustbin (or find ~/dustbin) is sufficient.
  2. The program, as written, does not deal with duplicate names from different source directories.
  3. You might want to look at the tar command that does all this, and more.

gasric 10-26-2013 01:54 PM

Quick update!

Hi michaelk, yeah i had that in there before and have changed it back but thanks for the input buddy! :)

Right grail, cheers for your help buddy so far and i have read what you posted and have taken it on board. What you have said makes a lot of sense but here's more for you! haha

New delete code:
Code:

if [ -f $1 ]
file=`basename $1`
then echo `readlink -f $file` >> ~/fp.txt && mv $1 ~/dustbin && echo "$1 Moved" || echo "File does not exist"
fi

Now you did say the echo was not needed but if i remove it i have a permission denied and im the root user so thats totally messed my head around.
The code above does work with no errors popping up and stores the full file path of a deleted file correctly.

Answer to Q3.
I cant guarantee these files will be unique but im just starting small for now and then moving on as i get a bit more knowledgeable about scripting, so its more of can i do it but simply. Hope that helps better understand my madness?

Answer to Q4.
Well i was trying to move the file back by calling each part, as in "file name" "it's stored location" send to "location".
To be honest as i have been typing this out explaining what i wanted, it makes no sense so....Answered my own question of why it didn't work to start with. >_<

So heres my new code:
Code:

#!/bin/sh
if [ "$1" ]
then cd ~/dustbin
grep `"$1" ~/fp.txt`
restore=`grep "$1" ~/fp.txt`
mv ~/dustbin/$1 $restore
fi

The BUT.... it restores the file to the location and every thing is A OKAY! except that it pumps out this error:

line 4: alpha: command not found
usage: grep [option]... pattern [file]....

line 4: grep `"$1" ~/fp.txt`

Why is this happening?

gasric 10-26-2013 01:57 PM

WOW please forget the last question about LINE 4: grep...

I removed it as it was not needed and feel a bit stupid after not just checking what was happening!:/

gasric 10-26-2013 02:08 PM

Hi PTrenholme, sorry didn't see your post till after I posted back.

Thanks for the input and i have read what you have done and sort of understand what you are trying to do but thats very complex for me right now, but may not be for you.

Thanks very much and will revert back to it in the near future. :)

grail 10-27-2013 06:29 AM

Referring to your remove script, how would you call it? I am specifically concerned with the reference to the basename function:

See this example:
Code:

./remove.sh /home/gasric/tmp_file
readlink -f ... not sure if you looked up what is happening here, but if we assume you are at root (/) and issue the above, your readlink command will return as follows:
Code:

$ readlink -f tmp_file
/tmp_file

As you can see this has nothing to do with the file existing. Also, it means when you call your restore function it will place it back in the root level instead of where it was deleted from.
If you are not root this will cause problems and it will be in the wrong place.

wrt to restore script, once the file has been restored you do not remove its information from fp.txt. This means you could use the same file name again and will now get errors of no such file.
Something to think about

From a programming perspective, I try to do any new tasks in the shell first and then simply copy that exact line into a script. From there you can replace variables and create functions as you
require. One thing to be wary of that most forget as you do it visually, is how to check a file exists both to be removed, be restored and is not already been restored.

Keep going though, you are getting somewhere :)

As for PT's version, this is a replacement for your remove option so if you take it a line at a time it is not complicated, the large amount of printf statements is to make it clear when you have
success or failure (always a good habit)

@PTrenholme - the below is not correct. You can call find without a root directory and it will simply default to your current location. Admittedly this is not a good habit :)
Quote:

Well, the find command requires a root directory, and you have not specified one.

gasric 10-29-2013 04:18 AM

Hey grail, right i have read up on readlink -f and it does work as it saves the full path and i have adapted my code to amend the fp.txt file when a file is restored from it so there will be no duplications stored in the fp.txt file.

Now i need your help once again as i have now started to request the user to input a file location if the file with the same name already exists in the location its trying to restore to.

Code:

if [ "$1" == ""]
                                                       
then echo "Please specify file to be restored"               
fi

if [ -f "$1" ]
                                                                               
then cd ~/dustbin       
        echo File already exists!                                                       
        echo Where would you like to restore to?
        read location
        location1=`readlink -f $location`
        mv -i $1 "$location1"/
else

if [ "$1" ]
then cd ~/dustbin
restore=`grep "$1" ~/fp.txt`
mv ~/dustbin/$1 $restore && echo "$1 Restored" && > ~/fp.txt || echo "File does not exist"
fi
fi

Really appreciate all the help and advice you have given so far. :)
I will keep at it for now and i hope i can work it out but its beating me right now lmao! ;(

SAbhi 10-29-2013 04:33 AM

Quote:

if [ "$1" == ""]

then echo "Please specify file to be restored"
fi
should be like (just a rough idea) :
Code:

if [[ -z $1 ]];
then
echo -e "[USAGE]; $0 filename" # that will tell the user that an argument is required to initiate the script.
exit 1
fi

#initiate some variable if needed.

if [ -s "$1" ] # if file does exist and has something in it then do something.
then
echo -e "confirm file exist"

#perform the move operation
else
echo -e "file does not exist or is empty, exiting..."
exit 1
fi



All times are GMT -5. The time now is 12:05 AM.