I have a Java application that creates and runs a process (x.exe). When process x is executed, it prompts the user to enter a password. How to pass this password to the user?
I tried to use the OutputStream of the process and wrote the password to the stream but still the process didn't run.
Runtime r=Runtime.getRuntime();
Process p=r.exec("x.exe");
p.getOutputStream()//.use to pass the arguments
You need to flush the stream, and also, it maybe expects a CR at the end of the password to simulate the ENTER key the user types at the end of the password. This works for me in Linux:
Runtime r = Runtime.getRuntime();
Process p = r.exec("myTestingExe");
p.getOutputStream().write("myPassword\n".getBytes()); // notice the `\n`
p.getOutputStream().flush();
Some caveats:
This works in Linux with '\n' at the end, maybe in Windows you would need \r instead (honestly I'm not sure of how Windows handles the "ENTER" key in the input)
I'm using "myPassword\n".getBytes() but a more complete value would be new String("myPassword".getBytes(), Charset.forName("MyCharsetName")); (where "MyCharsetName" is a supported encoding) if you are using an encoding like "UTF-8".
As already was pointed out you can consider to use an Expect-like library for interacting between your Java program and a spawn OS process. Basically, you would need to wait until the password prompt gets available in the process input stream and then write the password terminated by the end-of-line to the process output stream.
If you decide to go with a third party library approach I'd recommend you to give a try my own modern alternative to expect4j and others. It is called ExpectIt has no dependencies and is Apache licensed.
Here is a possible example with the use of the expect library:
Process process = Runtime.getRuntime().exec("...");
Expect expect = new ExpectBuilder()
.withInputs(process.getInputStream())
.withOutput(process.getOutputStream())
.withErrorOnTimeout(true)
.build();
expect.expect(contains("Password:"));
expect.sendLine("secret");
expect.close();
Note: the contains method is statically imported.
You can try library like expect4j to interact with the external process
Related
The application works fine on Windows machines where DB2 is setup in English language, since need to validate the executed commands output like
> db2 attach to DB2 user db2admin using xxxxxx
Instance Attachment Information
Instance server = DB2/NT64 10.5.1
Authorization ID = DB2ADMIN
Local instance alias = DB2
Actually the above output is redirected into a text file and then validated by a Java code as
String message = Utils.readFile(filePath);
message = message.trim().replaceAll("\\s+", " ");
String upperStr = message.toUpperCase();
if (upperStr.indexOf("INSTANCE ATTACHMENT INFORMATION") != -1
&& upperStr.indexOf("AUTHORIZATION ID") != -1)
return "SUCCESS";
else
return "FAILURE";
But the issue is: On Japanese/Chinese machine the DB2 commands generate the output in their language e.g. In Japanese Machine
インスタンス?Eアタッチ?﨣・インスタンス?Eサ?[バ?[ = DB2/NT 10.5.5 許可 ID = DB2ADMIN ・?[カル?Eインスタンス別名 = DB2
So, how to modify that language to work normally like English?
Or could the command's output be generated in English only?
It seems that you chose an unreliable way to determine success (or failure) of an external program. Apart from the language problem you are dealing with, there are other possible issues with trying to save and parse program output.
A better way to check the external program result is to look at its exit code. By convention, most programs (DB2 CLP included) return 0 when they end successfully and a different value if there is some sort of a problem. You can find more information in the manual.
When executing an external program from Java, you can use Process.exitValue() to obtain its exit code.
I have a log file on a UNIX server which is dynamically changing.
I want to build an application to view that file on a Java GUI using Swings in multiple pages using SSH.
I am using JSCH Library to execute the "more" command for that log file. But in the output, some special characters like '[24;1H[K[7m' are printed. How to remove these special characters.
I am using the following code
session.setConfig("StrictHostKeyChecking", "no");
session.connect(30000);
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
Thread.sleep(3000);
PrintStream ps = new PrintStream(channel.getOutputStream(), true);
ps.println("more " + fileName);
The output is :
[?7h[?1l(B=[24;1H[K************ Start Display Current Environment ************
[24;1H[K[7mSystemOut.log (0%)[m[24;1H[24;1H[KID: soacore.FP6123 BuildVrsn: null Desc: WebSphere Process Server 6.1.2.3
[24;1H[K[7mSystemOut.log (0%)[m
As you can see, some special characters are printed. How to remove those special characters?
I found out the answer. Just one line of code does the trick.
((ChannelShell) channel).setPtyType("dumb");
Adding the above line before the connect() removes all the non printable characters.
If you are developing a terminal emulator you can consider using a third-party library that could help you to manage the input data flow, specially dealing with the ANSI terminal control characters you are encountering. Tools like Expect are traditionally used to automate interacting between a program and text based terminal systems.
There are several exiting Expect for Java implementations you can use. Here I'd like to promote my own open source tool called ExpectIt. It supports filtering the input data to remove unwanted characters like terminal control that you may find very useful for your use case. It has other advantages stated on the project page.
Here is an example of using ExpectIt to iterate through the results of the more command. Note registering the removeColors filter which filters out the terminal characters.
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("shell");
Expect expect = new ExpectBuilder()
.withOutput(channel.getOutputStream())
.withInputs(channel.getInputStream(), channel.getExtInputStream())
// register filters to remove ANSI color characters
.withInputFilters(removeColors())
.build();
try {
channel.connect();
// define the command line prompt
final String PROMPT = "...";
expect.expect(contains(PROMPT));
expect.sendLine("more <file>");
while (true) {
// expect either the end of the page or the end of the command
MultiResult result = expect.expect(anyOf(contains("--More--"), contains(PROMPT)));
// print the result
System.out.println(result.getBefore());
// exit if reach the end
if (result.getResults().get(1).isSuccessful()) {
break;
}
// scroll to the next page
expect.send(" ");
}
The code below works assuming that the corresponding methods are imported statically.
Currently, I have a batch file that is basically running an executable jar.
Like this...
java -jar foo.jar
I have code in progress that is executing that batch file and piping out the values it returns into a txt document. I am then reading in that text document and parsing the info accordingly.
However, this is an ugly way of handling this and could lead to many issues down the road. I am basically just looking for a way in progress to execute a os-command and retrieve it's results without writing it to a file and reading back in.
I am running OpenEdge 10.1C
DEFINE INPUT PARAMETER iJarInput AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER oJarOutput AS CHARACTER NO-UNDO.
DEFINE VARIABLE cOut AS CHARACTER NO-UNDO.
DEFINE VARIABLE cCmd AS CHARACTER NO-UNDO.
ASSIGN
cCmd = batchFile + " " + iJarInput.
OS-COMMAND SILENT VALUE(cCmd).
INPUT FROM VALUE(outFile).
REPEAT:
IMPORT UNFORMATTED cOut.
oJarOutput = oJarOutput + cOut.
END.
You can call external shared libraries.
http://documentation.progress.com/output/OpenEdge112/oe112html/ABL/wwhelp/wwhimpl/common/html/wwhelp.htm#href=Programming%20Interfaces/15dvpinch08epi.089.5.html&single=true
You could, for instance, use that capability to create a "shim" to your JAR.
I am currently writing a service that should take cleartext commands and then return something according to thoose commands, which is also in cleartext.
I have this odd problem with BufferedReader, or, it might be telnet that is odd, for some reason the BufferedReader reads the first command, however that command is ignored no matter what i do, which i can get around by sending the first command twice, but that is just stretching it a bit, in my oppinion.
The code below is in a run() method.
Then i set out as a PrintWriter and in as a BufferedReader.
The runs variable is by default true.
out = new PrintWriter(handle.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(handle.getInputStream()));
while (runs) {
String msg;
msg = in.readLine();
String[] command;
command = msg.split(" ", 3);
/* do something with the command */
}
So my question is if BufferedReader is ignoring the first line or is it telnet that is not coorperating with me?
If it is something else, then please enlighten me.
EDIT
I got this debug message:
Debug: ���� ����'������/nick halmark
so i suppose that it is about all the questionmarks.
I am actually using the latest Putty since i am developing on a windows box... and as far as i recall... then it does not exist by default
If you are using PuTTY, you need to choose the "Raw" Connection Type.
Microsoft telnet servers like to have some content/protocol negotiation at the beginning, so PuTTY will do this by default as per the RFC 854 spec. That's the garbage that you are reading.
I'm writing a program to find the file size of files.
Is it possible in java?
In PHP I know there is a filesize().
Another alternative was using ab http:// in unix but how is it integratabtle with java?
What do you think is the best/most efficient way to attack this?
You can use java Runtime to execute the command and read the output from the buffer and display it.
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("ab http://whatever ");
// read the stream into the buffer and display the results.
If you have the file locally, then you can use File.length()
Retrieve a page, extract links, and then only request the header for each uri.
filesize() in PHP may be dicey, as whether or not you're allowed to use it on a remote file will be entirely up to the configuration of your host. You might consider curl instead
Using curl from a shell, for instance, to look at an ad on the rhs of the page as I write this:
curl -I http://static.adzerk.net/Advertisers/180414077f314dbdbaa8d8e2f7898249.gif
...yields, among other things:
Content-Type: image/gif
Content-Length: 17798
...which may be what you're looking for. Within PHP, get the equivalent with CURLOPT_NOBODY