0

I am having some issues where running a script that I have placed in my file browsers scripts folder making it runnable from the right-click menu, is not capable of actually producing a prompt for user-input when the read command is called.

Is there any way to force it to create the prompt?

This is the code I am using to test it, nothing much:

#!/bin/bash
read -p "Hour " answer
hours=$answer

My script is being invoked from the right-click menu in Nemo (the file browser in Linux Mint 19.2), being installed in /home/username/.local/share/nemo/scripts.

read works fine from a terminal, or running a script with "run in terminal", but the right-click menu in Nemo doesn't start one.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
underscore
  • 49
  • 1
  • 6
  • 2
    Are you sure stderr (which is where the prompt is printed to) is directed to the TTY? Also, are you sure the script is being run in such a way that the `#!/bin/bash` shebang is honored? (`sh yourscript`, for example, will ignore that shebang and run your script with `sh`, not `bash`; `sh` is not guaranteed to support `read -p`). – Charles Duffy Oct 07 '19 at 14:57
  • 1
    `hours=$answer` doesn't do anything useful. You can just write `read -p "Hour " hours` instead. – chepner Oct 07 '19 at 14:58
  • 1
    ...as it is, though, this question isn't complete enough to let someone else reproduce the problem itself. If it's your file browser that's invoking the script with stderr redirected, or with `sh` instead of bash, there's not enough information here for us to know which "file browser" this is, or how it's configured. Please ensure that your question is a [mre], with everything needed for someone else to see the problem themselves included. – Charles Duffy Oct 07 '19 at 14:59
  • 1
    ...there *are* a few things you can do to test. `echo "stdout"; echo "stderr" >&2`, and see if both are printed; `echo "Bash version: $BASH_VERSION"`, and see if the version string prints. – Charles Duffy Oct 07 '19 at 15:00
  • 1
    Another thing you can do to test stderr: `if [ -t 2 ]; then echo "stderr is directed to the TTY"; else echo "stderr is NOT directed to the TTY"; fi` – Charles Duffy Oct 07 '19 at 15:07
  • @chepner Ye, in this example its not helping much, but this is only a small portion of a main script that I am running by itself in another empty script to problem solve the read command issue. Thanks for the info though! – underscore Oct 07 '19 at 17:11
  • @CharlesDuffy Hey, sorry for not giving enough info. I have updated the post with an edit now that hopefully provides some more insight. I'll have a look at trying the stuff you mentioned during lunch in a few hours. Thank you for the replies! – underscore Oct 07 '19 at 17:13
  • 1
    If you expect `read` to display a GUI when it's not connected to a terminal then sorry, that's not at all how Bash works. You can use tools like `zenity` to display dialog boxes if that's what you need. – tripleee Oct 07 '19 at 17:15
  • @tripleee I dont need a display as such, I am looking for user input, so a dialogue box where the user can input something to later be used by a script – underscore Oct 07 '19 at 17:39
  • `.sh` as a filename doesn't say anything about how a program is executed -- on UNIX, there's no relationship at all between filename and how a program is run; for that matter, it's conventional / good practice to not give executable files extensions at all. (See an essay on the subject at http://www.talisman.org/~erlkonig/documents/commandname-extensions-considered-harmful/; more tersely -- you run `ls`, not `ls.elf`, even though `ls` is an ELF-format executable; same thing for scripts). – Charles Duffy Oct 07 '19 at 17:51
  • @underscore, ahh, you want a dialog box to be popped up on an otherwise-headless script? Bash doesn't do that at all; it has no built-in graphical capabilities, so you need to use 3rd-party programs to do the prompting for you (like `zenity`, which tripleee mentioned above). – Charles Duffy Oct 07 '19 at 17:53
  • ...so, `read` reads from your script's stdin; it's the responsibility of the software that's starting your script to run it with stdin (stdout, stderr, etc) connected to a terminal if that's what you want. – Charles Duffy Oct 07 '19 at 17:55
  • Of course, you can have script-1 that launches a new terminal with a shell running script-2 inside it, if that's what you intend. Exactly how to do that depends on which terminal program you're using; usage is different between Konsole (KDE), xterm (traditional UNIX), Gnome-Terminal, etc. – Charles Duffy Oct 07 '19 at 17:55
  • @CharlesDuffy Ah, then that is probably where I've been mistaken. I thought calling/invoking the read command would actually create a terminal window I could use to create user input. Alright, I'll have a look at zenity or do as you mentioned having a script that opens a terminal that then runs my other script. All I essentially am after is actually be able to get user input and use it to add to a text file later on in the script. – underscore Oct 07 '19 at 19:19
  • @tripleee I guess you were right all along and I just misunderstood what you meant with GUI. Sorry about that. – underscore Oct 07 '19 at 19:41
  • Right. bash runs with its stdin/stdout/stderr connected to a terminal, which is to say, the terminal needs to exist first, *then* a copy of bash can be invoked with its stdin, stdout and stderr connected to the PTY ("pseudoteletype") that your terminal application created when it initialized. (In the old days, instead of PTYs, you had physical hardware TTYs -- something like a [DEC VT100](https://en.wikipedia.org/wiki/VT100) connected via a serial port). When bash is started headlessly, its stdin/stdout/stderr are typically connected to `/dev/null`. – Charles Duffy Oct 07 '19 at 19:45
  • ...granted, it's *possible* to reconnect them later (`exec >something` will reconnect the current shell process's stdout to the file `something`), but it's a for-experts-only type of thing. – Charles Duffy Oct 07 '19 at 19:48
  • Possible duplicate of https://stackoverflow.com/questions/7035/how-to-show-a-gui-message-box-from-a-bash-script-in-linux – tripleee Oct 07 '19 at 19:57
  • @tripleee Thanks for the link to that post! Not entirely sure mine is a duplicate, misguided as I may have been, to begin with. It seems they are looking for a way of strictly printing something whilst I am looking to fetch user input. Regardless it set me on the right path so its a great referance! Thanks for your help in solving this cryptic mystery I created out of my incompetance xD – underscore Oct 07 '19 at 20:33
  • @CharlesDuffy Thank you so much for sticking with me through my lack of expertise, its been really helpful. I got it working, fairly quickly when I took tripleees advice of trying zenity instead. I'll add a comment below on how I solved it. Thanks again for helping out, sorry the original post sucked. – underscore Oct 07 '19 at 20:35
  • Glad to help! Since you wrote a useful answer (very closely related to but not *exactly* a 100% match for tripleee's proposed duplicate in my view), I've tried to edit the question to focus it a little more directly on the problem; hopefully other folks having the same problem will be able to find and learn from the Q&A pair! – Charles Duffy Oct 07 '19 at 20:46

1 Answers1

1

This was based on a misunderstanding of what the read command does. As pointed out by both tripleee and charles duffy, the read command can't actually create its own terminal window. On my OS, Zenity is preinstalled, so the following works correctly as a replacement for read -p 'This is a test! ' myvar:

#!/bin/bash
myvar=$(zenity --entry --text="This is a test!")
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
underscore
  • 49
  • 1
  • 6