0

I have a shell script, test.sh, that internally invokes a Java application MyApp.

#!/bin/bash
# Invoking MyApp
java MyApp

MyApp reads 2 parameters, username and password, from the console. Running this script will execute the Java app which will prompt the user to enter a username and password

Username: user
Password: ****

I want to automate the execution of this shell script. How can I pass the username and password as parameters to the script test.sh?

What I've tried:

Used the indirection operator with a file containing the parameters

$ ./test.sh <input

Used the shortcut for the above method

$ ./test.sh <<!
user
password
!

In both cases Console console = System.console(); inside MyApp.java sets console as null.

PS: Looking for ways to accomplish this without modifying the script or the Java app. "No, this cannot be done!" is also an acceptable answer.

Krishter
  • 489
  • 8
  • 24
  • You should not need any indirection. The script from your first example should just work, assuming the classpath is set correctly. – Evgeny Tanhilevich Aug 09 '16 at 14:19
  • do you have access to the source code of the Java app? can you change it ? – Yazan Aug 09 '16 at 14:26
  • Thank you for your comments. I don't think my question was properly understood. I have tried to make it a bit more descriptive. In short, I have a Java app that reads from console. This Java app is invoked from the shell script. – Krishter Aug 09 '16 at 14:53
  • a possible dupe of http://stackoverflow.com/questions/9075478/is-there-a-way-to-input-automatically-when-running-a-shell?noredirect=1&lq=1 ... funny thing you mentioned it yourself, Krishter. –  Aug 09 '16 at 15:40

3 Answers3

3

Echo can be used to pipe (|) input to any program:

echo -ne "user\npassword\n" | java MyApp

(Here newline \n symbolises the return key being pressed, -n stops echo appending another newline and -e enables interpetation of the newlines )

Drgabble
  • 618
  • 5
  • 17
  • Thank you for your answers. I don't think my question was properly understood. I have tried to make it a bit more descriptive. In short, I have a Java app that reads from console. This Java app is invoked from the shell script. – Krishter Aug 09 '16 at 14:53
  • @Krishter have you tried what Drgabble proposed? It actually pipes the text to the app, so it should work. OTOH, if you have no console, then you can't pipe to it; use stdin/stdout directly instead. –  Aug 09 '16 at 14:55
  • @vaxquis, This solution presumes that I can edit the shell script. Unfortunately this is not an option. If I understand the second part of your comment, you're suggesting changing the source code of the Java app to not read from the console? Again I'm looking for options where the pre-built binaries do not have to be changed. – Krishter Aug 09 '16 at 15:08
  • @Krishter you're contradicting yourself then. As far as I understand what you said, you expect to a) have the source code and binaries untouched, b) have binary execution script untouched, c) modify the behaviour of closed (due to the exact script content; if it e.g. had an option to pass more arguments etc. it wouldn't be a problem) script-binary-source code system. As such, the only viable solutions are either breaking the OS by replacing the `bash` executable, runtime code injection, or similar tricks/hacks. –  Aug 09 '16 at 15:15
  • @vaxquis I do not see any contradictions. I have not mentioned anywhere in my question that modifying the source code is an option. I would've done it myself without posting it here on SO, if that were the case. This is a real world scenario involving pre-built binaries and along the lines of the following questions, the primary difference being the Java app actor. http://stackoverflow.com/questions/9075478/is-there-a-way-to-input-automatically-when-running-a-shell http://unix.stackexchange.com/questions/42554/automating-textual-input-from-a-bash-script-without-using-eof – Krishter Aug 09 '16 at 15:20
  • @Krishter if you want input automation (for testing/mocking/etc), you should've a) mentioned that in your question, b) added a relevant tag(s) to your question - generic input automation is, strictly speaking, a hack vs regular app use cases. As it (your question) currently stands, Drgabble already gave you a valid answer. –  Aug 09 '16 at 15:39
2

The program expect can be used to simulate human console input:

#!/usr/bin/expect
spawn ./test.sh
expect "Username: "
send "user\r"
expect "Password: "
send "password\r"
interact

(copy this to a file and then run the file e.g. ./expect_script.sh)

Drgabble
  • 618
  • 5
  • 17
  • This is a great solution, in line with the expectation. "expect", though needs to be installed separately, since the minimal install of the Linux distro does not have it. I'll wait if any answers indicates built-in features that can accomplish this. Otherwise this sure fits the brief. Thanks again! – Krishter Aug 09 '16 at 15:47
  • 1
    Small correction on the first line though. Should be `spawn ./test.sh` – Krishter Aug 09 '16 at 15:48
0

Echo can be used to pipe (|) input to any program:

echo -ne "user\npassword\n" | ./test.sh

(Here newline \n symbolises the return key being pressed, -n stops echo appending another newline and -e enables interpetation of the newlines )

Drgabble
  • 618
  • 5
  • 17
  • Thanks for your answer. I tried this after I read your earlier answer. The result is the same. "Console" is null. – Krishter Aug 09 '16 at 15:27
  • 1
    While this code may answer the question, providing additional context regarding *how* and/or *why* it solves the problem would improve the answer's long-term value. - [From Review](http://stackoverflow.com/review/low-quality-posts/13280280) – Michael Parker Aug 09 '16 at 16:12