5

I am putting together a simple file handling script, its all working nicely except at the end, I want it say do you want to perform another action and if the answer is yes then I want the script to start again. I know I need some kind of loop here ? Here is what I have:

#/bin/bash


echo "Select an option from copy , remove , rename , linking"
#read in user input into the action variable

read action

# if action is copy then continue proceed with the following
if [ $action = "copy" ]
then
echo "Please enter the filename you wish to copy"
read filename
# check if filename exists, if it doesn't then exit program
    if [ ! -e  $filename ] 
    then
    echo "$filename does not exist"
    exit 1
    fi
echo "Please enter the new filename"
read filenamenew
cp $filename $filenamenew
echo "$filename has been copied to $filenamenew"

# if action is remove then continue proceed with the following
elif [ $action = "remove" ]
then
echo "Please enter the filename you wish to remove"
read filename
# check if filename exists, if it doesn't then exit program
    if [ ! -e  $filename ] 
    then
    echo "$filename does not exist"
    exit 1
    fi
rm -rf $filename
echo "$filename has been deleted"

# if action is rename then continue proceed with the following
elif [ $action = "rename" ]
then
echo "Please enter the filename you wish to rename"
read filename
# check if filename exists, if it doesn't then exit program
    if [ ! -e  $filename ] 
    then
    echo "$filename does not exist"
    exit 1
    fi
echo "Please enter the new filename"
read filenamenew
mv $filename $filenamenew
echo "$filename has been renamed to $filenamenew"
fi

echo "Do you want to perform another file operation (yes/no) ?"
read answer

if [ $answer = yes ]
then "run script again"
exit 0
    elif [ $answer = no ]
    then echo "Exiting Program"
    exit 0
    fi
fi
8

before echo "Select an action ..."

answer=yes
while [ "$answer" = yes ]
do

in the end, replace

if [ $answer = yes ]
then "run script again"
exit 0
    elif [ $answer = no ]
    then echo "Exiting Program"
    exit 0
    fi
fi

by

if [ "$answer" = yes ]
then "run script again"
fi

done

echo "Exiting Program"
exit 0

what I did, is enclose programm in a while [$condition ] do ; ... done.

I just ensure condition was OK (answer=yes) in first loop.

  • The while loop will run as long as the answer variable is "yes". The script will "restart" the loop if you answer the question in the end with a "yes". – M_dk Sep 29 '15 at 13:36
6

The answers about looping are good ways to handle this. But for reference, there is nothing wrong with having the script re-invoke itself, thus /usr/local/bin/myscript could read:

#!/bin/sh
...
if [ yes = "$answer" ]; then
  /usr/local/bin/myscript
fi

You don't need an exit 0 in the other case because that will happen automatically. Also if you know you're in the same working directory at the end of the script as you were at the beginning, then you could avoid hard-coding the path of the script by instead just using $0.

There's one last refinement that is important. As written, the script process first started will spawn a second one, and wait for it to finish; the second may then spawn a third and wait for it to finish; and so on. This consumes resources, and there really is no work for those scripts to do when their progeny exit. So you'd do better to run them using the equivalent of a "tail-call" in programming. This is done using the command exec:

#!/bin/sh
...
if [ yes = "$answer" ]; then
  exec /usr/local/bin/myscript # or exec $0
fi

This works just like before, except that the first process exits as it starts the second, and when the second finishes, if it hasn't spawned a third process, we go back directly to whoever launched the first process, presumably the shell.

  • 2
    +1 as exec is the way to go, here (otherwise each inner "/.../.../myself" will adds another layer/subshell) – Olivier Dulac Sep 29 '15 at 17:14
1

Try to wrap your script as a function and call it recursively:

#/bin/bash
do_file_action(){
  echo "Select an option from copy , remove , rename , linking"
  #read in user input into the action variable

  read action

  ...

  echo "Do you want to perform another file operation (yes/no) ?"
  read answer

  if [ $answer = yes ]
  then do_file_action
  exit 0
      elif [ $answer = no ]
      then echo "Exiting Program"
      exit 0
      fi
  fi
}

do_file_action

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.