restoring a file to their original location from a log file with paths - linux

I have made 1 script to move user specified files to the dustbin and create a log file with their original paths. Now I want to create a script that the user would only have to input the name of the file to restore it to where it was before and I cannot figure that out.
Here is the code so far:
delete script:
#!/bin/sh
#checks if the user has entered anything.
#if not displays message.
if [ $# -eq 0 ]; then #reads the number of characters
echo "Usage: del <pathname>" >&2
exit 2;
fi
#location of the dustbin
dustbin="$HOME/dustbin"
paths="$HOME/Paths"
if [[ ! -d $dustbin ]]; then #checks if the dustbin exists
mkdir $dustbin
else
[[ -p $dustbin ]] #if dustbin exists does nothing
fi
#creates a Paths folder to store the original location of file(s)
if [[ ! -d $paths ]]; then #checks if the Paths folder exists
mkdir $paths
else
[[ -p $paths ]] #if Paths folder exists does nothing
fi
#gets just the file name
for file in "$#"; do #reads all the arguments
if [[ -e $file ]]; then #checks if the file name exists
#moves the file(s) to the dustbin and writes the orginal file path to the paths.txt file.
find $file >> $HOME/Paths/paths.txt && mv "$file" "$dustbin"
echo "Deleting file(s) $file"
else
echo "The file $file doesn't exist."
fi
done
restore script:
With this I need to search for the file in the dustbin, match the file name to the paths text file that has the files original path and move to the said path.
#!/bin/sh
#checks if the user has entered anything.
#if not displays message.
if [ $# -eq 0 ]; then
echo "Usage: restore <File name>" >&2
exit 2;
fi
#checks if the file paths.txt exist
paths="$HOME/Paths/paths.txt"
if [[ ! -f $paths ]]; then #checks if the Paths file exists
echo "The log file paths.txt doesn't exist. Nothing to restore"
fi
#takes the user input checks if the dustbin exists.
for file in "$#"; do
if [[ ! -d dustbin ]]; then
echo "dustbin doesn't exist"
else
cd $HOME/dustbin
fi
#looks for the user specified file.
if [[ ! -e $file ]]; then
echo "File $file doesn't exist"
else
#restores the file to the original location
restore="grep -n '$file' $paths" #no idea how to do it
mv $file $restore
fi
done
this part I have no idea how to do. I need it to read the user input in $file from the paths.txt and use that stored path to move the $file from the dustbin to the file path stored in the paths.txt file.
#restores the file to the original location
restore="grep -n '$file' $paths" #no idea how to do it
mv $file $restore

So, I think you will want to move the file back to where it originally was using mv.
mv "dustbinPath/$file" "orginalPath/$file"
This will move it from the dustbin path to the originalPath.
EDIT:
If you want to grep the path file for it, you can set a variable to the output of a command like:
originalPath=$(grep 'what_to_grep' file_to_grep.txt)
After you do that that use it in the mv above appropriately (whether the text file contains that file name or not) to move it out.
You can read more about setting a variable to the output from a command here. You might have problems if there are multiple lines that have it however.

In the del script I changed find to realpath so it looks like this:
#gets just the file name
for file in "$#"; do #reads all the arguments
if [[ -e $file ]]; then #checks if the file name exists
realpath $file >> $HOME/Paths/paths.txt && mv "$file" "$dustbin"
echo "Deleting file 'basename $file'"
else
echo "The file $file doesn't exist."
fi
done
and the restore script I added a new variable
rest="$(grep -e $file $paths)" #looking in to the paths.txt file for filename match
#looks for the user specified file in the dustbin.
if [[ ! -e $dustbin/$file ]]; then
echo "File $file doesn't exist"
elif [[ -e $rest ]]; then #if the $file exists in the original path adds an extension .bak
mv $dustbin/$file $rest.bak
else
mv $dustbin/$file $rest #restores the file to the original location
echo "$file restored"
fi

Related

Shell script to check whether the entered file name is a hidden file or not in RadHat Linux

How do i create a script to check for the file is hidden or not?
#!/bin/bash
FILE="$1"
if [ -f "$FILE" ];
then
echo "File $FILE is not hidden."
else
echo "File $FILE is hidden" >&2
fi
but it is unable to do so. Please help me.
Check if the filename begins with .:
file=$1
base=$(basename "$file")
if [[ $base == .* ]]
then echo "File $file is hidden"
else echo "File $file is not hidden"
fi
You essentially have to check if filename starts with . (period).
filename=$(basename -- "$FILE")
Then you have to use pattern matching
if [[ $filename == .* ]]
then
# do something
fi
The test command would be:
[[ "${file##*/}" == .* ]]
It's necessary to remove the path, to see if file name starts with .. Here I used prefix removal. It's the most efficient, but will choke if a file contains slashes (very unlikely, but be aware).
A full script should include a test that the given file actually exists:
#!/bin/bash
file=$1
[[ -e "$file" ]] && { echo "File does not exist: $file" >&2; exit 1; }
if [[ "${file##*/}" == .* ]]; then
echo "Hidden: $file"
else
echo "Not hidden: $file"
fi
You could also list all hidden files in a directory:
find "$dir" -name .\*
Or all not hidden files:
find "$dir" -name '[^.]*'
Depending on the task, it's probably better to use a list of hidden or not hidden files, to work on.
Also, by default, ls does not list hidden files. Unless you use -a.

Using ls command result in a loop

I want to use the result of ls command in a loop to check if for example the first line is a directory, second etc.
For example I have this folder that contains one directory the script should display:
18_05_2018 is directory
enter image description here
Create a file named is_file_or_directory.sh containing:
cd "$1" || echo "Please specify a path" && exit
for i in *; do
if [[ -d $i ]]; then
echo "$i is a directory"
elif [[ -f $i ]]; then
echo "$i is a file"
else
echo "$i is not valid"
exit 1
fi
done
Make that file executable with:
sudo chmod +x is_file_or_directory.sh
Run the script specifying as a parameter the path that you want to analyze:
./is_file_or_directory.sh /root/scripts/
Output:
jeeves ~/scripts/stack # ./is_file_or_dir.sh /root/scripts/
databe.py is a file
is_file_or_dir.sh is a file
mysql_flask.py is a file
test is a directory
Here's a more detailed explanation of what is happening under the hood. The variable $1 is, in Bash, the first parameter sent to the script. In our case it is the path where the script will perform its actions. Then we use the variable $i in the loop.
$i content will be every file / folder name in the path $1. With -d and -f we check if $i is a file or a folder.

Check that two file exists in UNIX Directory

Good Morning,
I am trying to write a korn shell script to look inside a directory that contains loads of files and check that each file also exists with .orig on the end.
For example if a file inside the directory is called 'mercury_1' there must also be a file called 'mercury_1.orig'
If there isn't, it needs to move the mercury_1 file to another location. However if the .orig file exists do nothing and move onto the next file.
I am sure it is really simple but I am not that experienced in writing Linux scripts and help would be greatly appreciated!!
Here's a small ksh snippet to check if a file exists in the current directory
fname=mercury_1
if [ -f $fname ]
then
echo "file exists"
else
echo "file doesn't exit"
fi
Edit:
The updated script that does the said functionality
#/usr/bin/ksh
if [ ! $# -eq 1 ]
then
echo "provide dir"
exit
fi
dir=$1
cd $dir
#process file names not ending with orig
for fname in `ls | grep -v ".orig$"`
do
echo processing file $fname
if [ -d $fname ] #skip directory
then
continue
fi
if [ -f "$fname.orig" ] #if equiv. orig file present
then
echo "file exist"
continue
else
echo "moving"
mv $fname /tmp
fi
done
Hope its of help!
You can use the below script
script.sh :
#!/bin/sh
if [ ! $# -eq 2 ]; then
echo "error";
exit;
fi
for File in $1/*
do
Tfile=${File%%.*}
if [ ! -f $Tfile.orig ]; then
echo "$File"
mv $File $2/
fi
done
Usage:
./script.sh <search directory> <destination dir if file not present>
Here, for each file with extension stripped check if "*.orig" is present, if not then move file to different directory, else do nothing.
Extension is stripped because you don't want to repeat the same steps for *.orig files.
I tested this on OSX (basically mv should not differ to much from linux). My test directory is zbar and destination is /tmp directory
#!/bin/bash
FILES=zbar
cd $FILES
array=$(ls -p |grep -v "/") # we search for file without extension so put them in array and ignore directory
echo $array
for f in $array #loop in array and find .orig file
do
#echo $f
if [ -e "$f.orig" ]
then
echo "found $f.orig"
else
mv -f "$f" "/tmp"
fi
done

Do you know how I can create backup files automatically?

I backup files a few times a day on Ubuntu/Linux with the command tar -cpvzf ~/Backup/backup_file_name.tar.gz directory_to_backup/. I want to create a script that will create the file name automatically - check:
~/Backup/backup_file_name_`date +"%Y-%m-%d"`_a.tar.gz
if it exists, if it exists then replace "_a" with "_b" and then checks all the letters up to z. Create the first backup file that doesn't exist. If all the files up to z exist then add "_1" to the file name (with "_z") and check all the numbers until the file doesn't exist. Never change an existing file but only create new backup files. Do you know how to create such a script?
You can do something like
for l in {a..z} ; do
[[ -f ~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}.tar.gz ]] && continue
export backupname=-f ~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}.tar.gz && break
done
# test if $backupname is properly set, what if `z` is used? I'm leaving this to you
# then backup as usual
tar -cpvzf $backupname directory_to_backup/
This iterates over the letters and if the required file exists skips setting the backupname variable.
OK, I found a solution. I created the file ~/scripts/backup.sh:
#!/bin/bash
working_dir=`pwd`
backupname=""
if [ -z "$backupname" ]; then
for l in {a..z} ; do
if [ ! -f ~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}.tar.gz ]; then
backupname=~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}.tar.gz
break
fi
done
fi
if [ -z "$backupname" ]; then
l="z"
for (( i = 1 ; i <= 1000; i++ )) do
if [ ! -f ~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}_${i}.tar.gz ]; then
backupname=~/Backup/backup_file_name_`date +"%Y-%m-%d"`_${l}_${i}.tar.gz
break
fi
done
fi
if [ ! -z "$backupname" ]; then
cd ~/projects/
~/scripts/tar.sh $backupname directory_to_backup/
cd $working_dir
else
echo "Oops! can't create backup file name."
fi
exit
The file ~/scripts/tar.sh contains this script:
#!/bin/bash
if [ -f $1 ]; then
echo "Oops! backup file was already here."
exit
fi
tar -cpvzf $1 $2 $3 $4 $5
Now I just have to type ~/scripts/backup.sh and the script backs up my files.
Create a script which saves file with date like,
~/Backup/backup_file_name_${date}.tar.gz
and run that script a cron job if you want to take backup after some specific interval or run it manually if you dont have such requirement.

restore in linux bash scripting

Help needed. This is script that I use to perform a restoration of a file from dustbin directory to its original location. It was located before in root. Then using other script it was "deleted" and stored in dustbin directory, and its former location was documented in storage file using this:
case $ans in
y) echo "`readlink -f $1`" >>home/storage & mv $1 /home/dustbin ;;
n) echo "File not deleted." ;;
*) echo "Please input answer." ;;
esac
So when using the script below I should restore the deleted file, but the following error comes up.
#!/bin/sh
if [ "$1" == "-n" ] ; then
cd ~/home/dustbin
restore="$(grep "$2" "$home/storage")"
filename="$(basename "$restore")"
echo "Where to save?"
read location
location1="$(readlink -f "$location")"
mv -i $filename "$location1"/$filename
else
cd ~/home
storage=$home/storage
restore="$(grep "$1" "$storage")"
filename="$(basename "$restore")"
mv -i $filename $restore
fi
error given - mv: missing file operand
EDIT:
so okay, I changed my script to something like this.
#!/bin/sh
if [ $1 ] ; then
cd ~/home
storage=~/home/storage
restore="$(grep "$1" "$storage")"
filename="$(basename "$restore")"
mv -i "$filename" "$restore"
fi
and still I get error:
mv: cannot stat `filename': No such file or directory
You might want to do some basic error handling to see if $filename exists before you use it as part of mv:
For example, before:
mv -i $filename "$location1"/$filename
You should probably do a:
if [[ -e "$filename" ]]; then
# do some error handling if you haven't found a filename
fi
The -e option checks whether the next argument to [[ refers to a filename that exists. It evaluates to true if so, false otherwise. (Alternatively, use -f to check if it's a regular file)
Or at least:
if [[ -z "$filename" ]]; then
# do some error handling if you haven't found a filename
fi
The -z option checks whether the next argument to [[ is the empty string. It evaluates to true if so, false otherwise.
Similar comment about: mv -i $filename $restore in your else clause.
Here's a list of test options.
You do
cd ~/home
and
mv -i "$filename" "$restore"
while the file is located in the dustbin directory, therefore, it is not found.
Do either
cd ~/home/dustbin
or
mv -i "dustbin/$filename" "$restore"
or just do
mv -i "~/home/dustbin/$filename" "$restore"
and drop the cd.

Resources