1

I have a script with the following body:

FILE_NAME=$(getFileToImport)
echo Your file is $FILE_NAME

The function getFileToImport is made to ask the user to choose a file, then the function itself will work it out a bit, and I would like to store the name of this newly created file into the variable FILE_NAME.

The function looks like something like this:

getFileToImport()
{
    echo Give me a name for your file:
    read FILE_NAME
    #Some fancy stuff here
    echo $FILE_NAME
}

If I do the above, I will never see the echos of the function (saying "Give me a name for your file"), so the function will directly go into the read statement without giving instructions to the user.

If I just invoke the function, meaning:

getFileToImport

instead of

FILE_NAME=$(getFileToImport)

... everything will work but I won't have FILE_NAME set to be used in the rest of the script.

How can I make my function returning me a value but still keeping on showing the interactive part (echos and reads) to the user so that they know what to do?

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89
  • 1
    Prompts should go to stderr (or the TTY), not stdout. stdout is only for output, and prompts are status information for user consumption. You'll note that bash itself behaves this same way. `read -p` will also do the work of writing a prompt (to stderr) for you. – Charles Duffy Mar 07 '18 at 17:08
  • BTW, these are "functions", not "methods". Methods belong to objects, and bash isn't OO. – Charles Duffy Mar 07 '18 at 17:12
  • Thanks @CharlesDuffy, I've fixed the "method" word (with method I meant rather 'procedure', in the sense that it was doing something without returning). I've had a look at the question you marked as duplicate, but it doesn't have an accepted answer and it's not really the same thing (I don't only need to echo a sentence, but also list of files and bigger stuff). Would you mind re-open the question, or help me understand how I should use that other thread for this issue? Thanks a lot in advance – Matteo NNZ Mar 07 '18 at 17:24
  • Anything intended for the user should be written to stderr -- `echo "This is for the user" >&2`. Anything intended for the outer shell that created the subprocess to read should be written to stdout -- `echo "$result"`. That's... really about all there is to it. – Charles Duffy Mar 07 '18 at 17:26
  • Unless you're open to considering ways to have your functions save results in a way that don't involve command substitution at all -- there *are* other mechanisms, and sometimes they make more sense. For that, we probably still have duplicates, but it would be a different set. – Charles Duffy Mar 07 '18 at 17:26
  • `read -p 'Give me a name for your file:' FILE_NAME` is the only change that needs to happen to make your function given here work, and that's well-covered in the duplicate. If you have a more complex "real" use case, could you try to [edit] the question to reflect just enough of that complexity as to make the duplicate's inapplicability clear? – Charles Duffy Mar 07 '18 at 17:28
  • (see https://stackoverflow.com/questions/9938649/indirect-variable-assignment-in-bash, if you want to have your function doing the work of modifying a variable whose name is passed as an argument; in that case, you would be running `getFileNameToImport file_name`, and then referring to `"$file_name"` later, without any `$(...)` involved). – Charles Duffy Mar 07 '18 at 17:34
  • (re: lower-case variable names being used in my examples, btw, see the relevant POSIX specification at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html -- all-caps names are used for shell and environment variables meaningful to the shell or other POSIX-specified tools, whereas lowercase names are reserved for application use; following this name prevents you from stomping on an variable meaningful to other tools by mistake). – Charles Duffy Mar 07 '18 at 17:35
  • @CharlesDuffy alright, all clear. Maybe the minimal question I asked above is too minimal, but I'll try to read a bit more about all you said above and ask to re-open the question just if I don't find any answer to it. Thanks a lot! – Matteo NNZ Mar 07 '18 at 17:49

0 Answers0