Automatic enter input in shell command line [duplicate] - linux

This question already has answers here:
Have bash script answer interactive prompts [duplicate]
(6 answers)
Closed 5 years ago.
I am running a script (I can't edit it), and there are three yes/no questions. How can I automatically respond to these questions? I need to answer yes, yes, no (in that order).

Try this:
echo -e "yes\nyes\nno" | /path/to/your/script
From help echo:
-e: enable interpretation of the following backslash escapes

Pipe to Standard Input
Some scripts can take replies from standard input. One of the many ways to do this would be:
$ printf "%s\n" yes yes no | ./foo.sh
yes yes no
This is simple and easy to read, but relies on how your script internals handle standard input, and if you can't edit the target script that can sometimes be a problem.
Use Expect for Interactive Prompts
While you can sometimes get away with using standard input, interactive prompts are generally better handled by tools like Expect. For example, given a script foo.sh, you can write foo.exp to automate it.
Note: You can also use autoexpect to create a a script from an interactive session, which you can then edit if necessary. I'd highly recommend this for people new to Expect.
Bash Script: foo.sh
This is the script you might want to automate.
#!/usr/bin/env bash
for question in Foo Bar Baz; do
read -p "${question}? "
replies=("${replies[#]}" "$REPLY")
done
echo "${replies[#]}"
Expect Script: foo.exp
Here is a simplistic Expect script to automate the Bash script above. Expect loops, branching, and regular expressions can provide much more flexibility than this oversimplified example shows, but it does show how easy a minimal Expect script can be!
#!/usr/bin/env expect
spawn -noecho /tmp/foo.sh
expect "Foo? " { send -- "1\r" }
expect "Bar? " { send -- "2\r" }
expect "Baz? " { send -- "3\r" }
interact
Sample Interactive Session
This is what your interactive session will look like when you run the Expect script. It will spawn your Bash script, and respond as instructed to each different prompt.
$ /tmp/foo.exp
Foo? 1
Bar? 2
Baz? 3
1 2 3

Related

How can I import two libraries in a shell script?

How can I import bash and expect in the same script? I've tried the following example but it's not working:
#!/bin/bash
#!/usr/bin/expect
Both cannot be imported at the same time, only bash works.
There is some severe misunderstanding and/or misconception here.
#! aka she-bang does not import any library.
This simply indicates the OS which interpreter should be used to run the script.
For example if your script foo looks like
#!/bin/bash
echo foo
you can simply (assuming you set the executable permission on the script)
./foo
but if you omit the first line, you have to
/bin/bash ./foo
bash and expect are (very) distinct interpreted language, and hence you have to decide which language you want to use, and then use the appropriate interpreter.
Having two interpreter for the same script is a plain non-sense.
Both bash and expect cannot be used in the same script. It can be done like this.
#!/usr/bin/expect -f
spawn..... #actual code need to be run by using bash
expect "Enter password for store:"
send -- "password\r"
expect "Enter password:"
send -- "password\r"
expect eof
This code was used to run a jar file which requires a password. So by running this script file by using expect library it could be done. This script will enter the password automatically.For running the jar file it needed the sh library.

Simple commands not found bash (#!/usr/bin/expect)

I've recently started using bash to automate a windows rescue disk with chntpw. I'm trying to set up the program to use the expect command to listen for certain chntpw dialog questions and input the right answers without any user input. For some reason after setting up the bash script to use #!/usr/bin/expect rather than #!/bin/bash then many standard terminal commands are no longer understood.
I'm running the script by typing this into terminal:
user#kali:~/Desktop/projects/breezee$ bash breezee1.sh
The terminal output is as follows:
BREEZEE 1.0
Welcome to BREEZEE
breezee1.sh: line 9: fdisk: command not found
[Select] /dev/:
Here is my code:
#!/usr/bin/expect
clear
echo "BREEZEE 1.0"
echo "Welcome to BREEZEE"
fdisk -l
#list partitions
echo -n "[Select] /dev/:"
#ask user to choose primary windows partition
read sda
clear
echo /dev/$sda selected
umount /dev/$sda
sudo ntfsfix /dev/$sda
sudo mount -t ntfs-3g -o remove_hiberfile /dev/$sda /mnt/
cd /mnt/Windows/System32/config
clear
chntpw -l SAM #list accounts on windows partition
chntpw -u Administrator SAM
#now supply chntpw with values to run the password clear (this answers the prompts)
expect '> '
send '1\r'
expect '> '
send '2\r'
expect '> '
send '3\r'
expect ': '
send 'y\r'
expect '> '
send 'q\r'
expect ': '
send 'y\r'
clear
echo "Operation Successfull!"
chntpw -l SAM #list accounts on windows partition
In short, I'm trying to use standard bash/terminal commands alongside the expect commands. I'm probably going about this all wrong, so please correct me as I've been troubleshooting this for about three days and haven't gotten far :(
When you specify the application that should run your script, you can only use the scripting language that application will understand.
Clearly, Expect is not bash, and does not understand bash commands.
i suggest you separate those two scripts. Write the first part for !#/bin/bash, the second for Expect. Make the first script invoke the second script and redirect it to chntpw.
expect uses tcl not bash. So you can write your script in TCL when you use #!/usr/bin/expect.
For example, echo "BREEZEE 1.0" should be written as:
puts "BREEZEE 1.0"
And you should use exp_send instead of send.
From expect manual:
exp_send is an alias for send. If you are using Expectk or some other variant of Expect in the Tk environment, send is defined by Tk for an entirely different purpose. exp_send is provided for compatibility between environments. Similar aliases are provided for other Expect's other send commands.

predefined input in a nohup shell script [duplicate]

I have a script that calls an application that requires user input, e.g. run app that requires user to type in 'Y' or 'N'.
How can I get the shell script not to ask the user for the input but rather use the value from a predefined variable in the script?
In my case there will be two questions that require input.
You can pipe in whatever text you'd like on stdin and it will be just the same as having the user type it themselves. For example to simulating typing "Y" just use:
echo "Y" | myapp
or using a shell variable:
echo $ANSWER | myapp
There is also a unix command called "yes" that outputs a continuous stream of "y" for apps that ask lots of questions that you just want to answer in the affirmative.
If the app reads from stdin (as opposed to from /dev/tty, as e.g. the passwd program does), then multiline input is the perfect candidate for a here-document.
#!/bin/sh
the_app [app options here] <<EOF
Yes
No
Maybe
Do it with $SHELL
Quit
EOF
As you can see, here-documents even allow parameter substitution. If you don't want this, use <<'EOF'.
the expect command for more complicated situations, you system should have it. Haven't used it much myself, but I suspect its what you're looking for.
$ man expect
http://oreilly.com/catalog/expect/chapter/ch03.html
I prefer this way: If You want multiple inputs... you put in multiple echo statements as so:
{ echo Y; Y; } | sh install.sh >> install.out
In the example above... I am feeding two inputs into the install.sh script. Then... at the end, I am piping the script output to a log file to be archived and viewed for later.

call bash script and fill input data from another bash script

I have a bash script, a.sh
And when I run a.sh, I need to fill several read. Let's say it like this
./a.sh
Please input a comment for script usage
test (I need to type this line mannually when running the script a.sh, and type "enter" to continue)
Now I call a.sh in my new script b.sh. Can I let b.sh to fill in the "test" string automaticlly ?
And one other question, a.sh owns lots of prints to the console, can I mute the prints from a.sh by doing something in my b.sh without changing a.sh ?
Thanks.
Within broad limits, you can have one script supply the standard input to another script.
However, you'd probably still see the prompts, even though you'd not see anything that satisfies those prompts. That would look bad. Also, depending on what a.sh does, you might need it to read more information from standard input — but you'd have to ensure the script calling it supplies the right information.
Generally, though, you try to avoid this. Scripts that prompt for input are bad for automation. It is better to supply the inputs via command line arguments. That makes it easy for your second script, b.sh, to drive a.sh.
a.sh
#!/bin/bash
read myvar
echo "you typed ${myvar}"
b.sh
#!/bin/bash
echo "hello world"
You can do this in 2 methods:
$ ./b.sh | ./a.sh
you typed hello world
$ ./a.sh <<< `./b.sh`
you typed hello world

How to get output from bash shell [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
bash - automatically capture output of last executed command into a variable
For example
In Bash shell
user:/ & echo "Hello"
Hello
user:/ & date
Sat Mar 17 01:48:45 ICT 2012
How to get the "Hello" or "Sat Mar 17 01:48:45 ICT 2012" variables
I mean every output from command bash shell
The purpose of this point, I want to get those variables and do something with its.
Like, when echo Hello I want to reverse string to olleH and then print it out.
Something like this
echo "Hello"
olleH
More Information
In Command Line Interface ***Not in Shell Script
When I type a command echo,date (or whatever command) in the Command Line Interface, The output will show in the next line.
user:/ & echo "Hello" <br>
Hello
The "Hello" variable is the output of bash shell. So, I want to store output Hello into variable and pass into "Dictionary Script"
The Hello will matched and translated depend on Dictionary Script
Hello = Hi (Just example)
Now Hello translated into Hi, send back to shell and print out
Result
user:/ & echo "Hello" <br>
Hi
How can I grab the output?
Could I expose the Bash Shell source, edit and re-compile?
Could I grab from the /proc/BASHPID?
Attempt at answering edited question
From your edit, it sounds as if you want to have bash executing commands, but the outputs from bash should be passed to a 'transmogrifier' which changes the output according to your whims.
This is not going to be trivial; I'm not sure it will be usable for more than a few seconds of fun.
At one level, you want an interactive shell with its standard output (and maybe standard error) going to your modifier program:
bash -i 2>&1 | transmogrifier
For basic command line work, this will just about be usable, though line editing (even with just backspace) becomes a little problematic. Command line editing becomes intolerable if transmogrifier is changing what you appear to be typing as you type it. (I tried bash -i 2>&1 | tee, which worked surprisingly well, but tee just copies its input to its output; and I'm not sure why I chose tee instead of cat. An interrupt, though, killed the pipeline; just another thing you'd have to worry about.)
Attempt at answering unedited question
For the Hello, you would be best off using:
var1="Hello"
You could also use:
var1=$(echo "Hello")
For the date, you more or less must use the latter notation:
var2=$(date)
You can now do things with those variables, such as:
$ echo "$var1" | rev
olleH
$
Note that simple prompts such as '$' (for Bash and relatives) or '%' (for C shell and relatives) or '#' (for root) are conventional.
I had decided not to mention the use of backticks, but since mgilson commented about them, they do, indeed, exist, and you may come across them in older scripts, and you should not write them in your own scripts.
The $(...) notation for command substitution, as it is called, is simpler in nested scenarios, such as:
cd $(dirname $(dirname $(which gcc)))/lib
compared with the backtick notation for the same operation:
cd `dirname \'dirname \\\`which gcc\\\`\``/lib
(Don't even think of trying to get that second line into MarkDown for comments! That's why I've added this to the answer.)

Resources