Reputation: 23
I have created this function:
function promptFile()
{
while true;
do
read -p "Please provide a full path [q to quit]: " file
if [ $file == q ]; then
echo "Exiting.."
return 1
fi
if [ ! -f $file ]; then
echo "File does not exist, please try again"
else
echo $file
break
fi
done
}
To prompt a user for file location, ask again if file does not exist, and save the output to a variable if it does, the function is called:
tempLoc=$(promptFile)
if [ !tempLoc ]; then
fileLocation=$tempLoc
fi
Everything works well unless someone write a bad file location, then the echo is not shown until someone clicks q or inputs an existing file location. in which case the echo message will be printed * the number of bad inputs, as follows.
[root@tsting:0]# ./tst
Please provide a full path [q to quit]: tst1
Please provide a full path [q to quit]: tst2
Please provide a full path [q to quit]: tst3
Please provide a full path [q to quit]: tst4
Please provide a full path [q to quit]: q
File does not exist File does not exist File does not exist File does not exist Exiting..
[root@tsting:0]#
I'm guessing this happens because the loop collapses back printing all the echos as it happens, is there a way to avoid this and just print the echo when the wrong file location is entered ?
Upvotes: 2
Views: 862
Reputation: 44354
Several things here:
You don't need ()
with "function" (and visa versa). ()
is usually preferred, (except in Korn shell).
ALWAYS write error messages to stderr: >&2
, that is the main reason why it does not work. There are TWO instances where this is required.
Nothing to do with your issue, but it is a good idea to quote variable values, especially filenames: "$file"
. This is in case someone has whitespace in the filename. Not that anyone in their right mind would ever name a file or directory with an embedded space (Program Files). Using [[ ]]
rather than single brackets reduces the need, but does not remove it altogether.
Always declare variables inside functions as local
, unless you really need to use a global (which you usually don't). If you don't do that then the variables inside a function could stomp on those outside, particularly if you reuse the function in several scripts.
The if
statement after calling the function is incorrect. You are testing for true/false (which it won't be) and you have omitted a $
prefix.
promptFile()
{
local file
while true
do
read -p "Please provide a full path [q to quit]: " file
if [ "$file" == q ]; then
echo "Exiting.." >&2
return 1
fi
if [ ! -f "$file" ]; then
echo "File does not exist, please try again" >&2
else
echo "$file"
break
fi
done
}
tempLoc=$(promptFile)
if [ -n "$tempLoc" ]; then
fileLocation=$tempLoc
fi
Upvotes: 0
Reputation: 11216
Write the error to stderr
echo "File does not exist, please try again" >&2
You are saving all output from the function into the variable tempLoc
, so even if the user inputs a valid file it will have a load of junk in the variable with it.
Stderr is where error messages should go anyway though, so it's good practice to send them there even without this problem.
Upvotes: 2