Platypus shell script does not prompt for "read" command - macos

I have a shell script like this :
#!/bin/sh
echo "What's your favorite color ?"
read user_color
echo "You like $user_color"
Whatever the settings I try with Platypus, the prompt is never shown on execution, thus the variable is not defined and never displayed. Is this something possible ?

read requires a controlling terminal (or at least a usable standard input), presumably in your environment no such terminal/input exists and so read cannot read any information (and echo has no standard output to send data to, assuming you don't see that either).
This limitation is in the platypus documentation and a workaround using CocoaDialog is given there as well.

Related

Put command string on the bash prompt

Say I have bash prompt in the terminal:
host:~/dir $
how can I write a command to the prompt that the user can choose to run? Maybe there is a way to use readline(3) to put a command in the shell prompt?
In other words, I am looking to write a command here:
host:~/dir $ <write some command here>
I tried:
echo "write some command here" > /dev/stdin
but that didn't quite work - it doesn't seem to put it on the prompt, is there a way to do that?
What I am trying to do - When you hit up/down arrow keys with bash, your previous command shows up in the prompt, I am trying to read from another history file and put it on the prompt.
Without knowing more about what your use case is, I'd start by pointing you in the direction of whiptail. It's part of the base install of most Linux systems and it allows you to present an input box to the user, even allowing for the box to be pre-filled with a default value. A very simple example would look roughly like this:
whiptail --input "Want to run this?" 8 78 "<write command here>" --title "Dialog box title here"
There's a primer available on WikiBooks that does an adequate job of introducing most of its basic features, if you want to dive deeper.

getting interactive, multiple line, formatted input from stdin in bash

I want to be able to interactively get output from the terminal in a way similar to a hereDOC. Ie I want the user to be able to type multiple lines, then have that information passed into a file with all the formatting maintained. Something like this.
echo "Type your message below. To finish the letter type DONE by itself on a line"
file=mktmp
cat << DONE > $file
obviously this doesn't work, because the EOF is found before DONE. I thought about passing the user to something like VIM, but my less computer savy coworkers have a hard time with vim/emacs/nano.
You need to use an editor; standard input is just a stream of bytes, not an editor. However, you don't have to hard-code a specific editor. EDITOR is a standard environment variable meant to allow your script's caller to choose which editor is used.
: ${EDITOR:?Please set the environment variable EDITOR to the editor of your choice}
echo "Type your message below, then save and exit your editor."
"$EDITOR" "$file"
EDITOR is typically set by the user in their shell configuration file, but can be set on-demand when you run your script.
$ EDITOR=nano yourScript.sh
okay, so I came up with this, but please help me find something better or improve on it.
echo "Type your message below, to finish the letter press CTL+D"
mapfile message
file=`mktemp`
for x in `seq 0 ${#message[#]}`
do printf "${message[$x]}" >> $file
done
cat $file

how user can respond to system prompts using shell script

I am trying to automate something using shell script.
My question is when there is a system prompt, for e.g. "Do you want to continue (y/n):"
And I need to input y using my shell script, how can it be done ? So at the end when the system prompt displays on the shell then my shell script should be automatically able to enter y.
Thanks in advance.
You can try an expect script
It is used to automate control of interactive applications such as
telnet, ftp, passwd, fsck, rlogin, tip, ssh, and others. Expect uses
pseudo terminals (Unix) or emulates a console (Windows), starts the
target program, and then communicates with it, just as a human would,
via the terminal or console interface.
It is really quite easy using redirection, and there are several ways to do it. This uses a here string. First to generate that system prompt:
more one.sh
read -p "Do you want to continue (y/n): " ans
echo "Answer was $ans"
Now the script to run the program:
bash one.sh <<< 'y'
Output:
Answer was y
Warning! This works by redirecting the process's standard input stream. Some programs, particularly when getting passwords, access the terminal driver at a low level for security reasons.

Pre-filling a prompt in Bash

Writing a bash script, and I want to get user input. Awesome,
read -p "What directory should we save in? " -e FOLDER
Except that what I'd like to do, ideally, is have the user see something like:
What directory should we save in? /home/user/default/
with the cursor at the end of the line, and the ability to delete backwards or append or whatever. Essentially, pre-filling the user's input, but giving them the ability to edit it.
Readline obviously has the capability, but it appears to be not exposed in the read command. Any alternatives? I'd prefer to not have to use perl or such.
The constraint I'm working under is that I'm writing a single shell script that would be nice to disseminate widely, so should rely on as little pre-existing infrastructure as possible. rlwrap and read -i both work if their dependencies (rlwrap and bash version >> whatever I have, respectively) are available. Both good answers, choose whichever works for you.
$ read -p "What directory should we save in? " -i "/home/user/default/" -e FOLDER
What directory should we save in? /home/user/default/
that should work, right?
You can wrap the command in rlwrap, which provides instant readline capabilities: https://github.com/hanslub42/rlwrap
(rlwrap -P does what you want)
As far as a pure bash solution is concerned for the 3.2 line (which i am presuming you are using), I dont think its possible

How can I flush the input buffer in an expect script?

I'm writing an Expect script and am having trouble dealing with the shell prompt (on Linux). My Expect script spawns rlogin and the remote system is using ksh. The prompt on the remote system contains the current directory followed by " > " (space greater-than space). A script snippet might be:
send "some command here\r"
expect " > "
This works for simple commands, but things start to go wrong when the command I'm sending exceeds the width of the terminal (or more precisely, what ksh thinks is the width of the terminal). In that case, ksh does some weird horizontal scrolling of the interactive command line, which seems to rewrite the prompt and stick an extra " > " in the output. Naturally this causes the Expect script to get confused and out of sync when there appears to be more than one prompt in the output after executing a command (my script contains several send/expect pairs).
I've tried changing PS1 on the remote system to something more distinctive like "prompt> " but a similar problem arises which indicates to me that's not the right way to solve this.
What I'm thinking might help is the ability for the script to tell Expect that "I know I'm properly synchronised with the remote system at this point, so flush the input buffer now." The expect statement has the -notransfer flag which doesn't discard the input buffer even if the pattern does match, so I think I need the opposite of that.
Are there any other useful techniques that I can use to make the remote shell behave more predictably? I understand that Expect goes through a lot of work to make sure that the spawned session appears to be interactive to the remote system, but I'd rather that some of the more annoying interactive features (such as the horizontal scrolling of ksh) be turned off.
If you want to throw away all output Expect has seen so far, try
expect -re $
This is a regexp match on $ which means the end of the input buffer, so it will just skip everything received so far. More details at the Expect man page.
You could try "set -o multiline" or COLUMNS=1000000 (or some other suitably large value).
I have had difficulty with ksh and Expect in the past. My solution was to use something other than
ksh for a login shell.
If you can change the remote login to other than ksh (using the chsh command or editing /etc/passwd) then you might try this with /bin/sh as the shell.
Another alternative is to tell KSH that the terminal is a dumb terminal - disallow it from doing any special processing.
$ export TERM=""
might do the trick.

Resources