How to provide shellscript input from java - java

I have created the shell script to add two numbers. I want to execute that shell script from java. Can you please help me on this.
first_num=0
second_num=0
echo -n "Enter the first number-->"
read first_num
echo -n "Enter the second number-->"
read second_num
echo "first number + second number = $ (( first_num + second_num ))"
And I need a piece of code based on the "jsch" library

you can do it by getting the runtime, as next
Process p = null;
Runtime rt = Runtime.getRuntime ();
String rutaFinal=path+carpeta+"/";
System.out.println("** Executing command *****");
p = rt.exec("chmod x process.sh");
p = rt.exec ("sh process.sh");
p.waitFor();
Also you can execute commands one by one, hope this help!!!

Related

Adding double quotes symbol in ProcessBuilder

I am using ProcessBuilderto build my command. I want to build my command following this post:How do I launch a java process that has the standard bash shell environment?
Namely, my command is something like this:
/bin/bash -l -c "my program"
However, I am having difficulties to pass the double quotes into ProcessBuilder, as new ProcessBuilder(List<String> command) failed to phrase the command if I natively add double quotes to List<String> command. ProcessBuilder recognizes the double quotes as an argument.
Relevant code:
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
String csi_output = Command.runCommand(project_directory, csi);
public static String runCommand(String directory, List<String> command) {
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File(directory));
Process process;
String output = null;
try {
process = processBuilder.start();
//Pause the current thread until the process is done
process.waitFor();
//When the process does not exit properly
if (process.exitValue() != 0) {
//Error
System.out.println("command exited in error: " + process.exitValue());
//Handle the error
return readOutput(process);
}else {
output = readOutput(process);
System.out.println(output);
}
} catch (InterruptedException e) {
System.out.println("Something wrong with command: " +e.getMessage());
} catch (IOException e) {
System.out.println("Something wrong with command: " +e.getMessage());
}
return output;
}
Ps: I do want to use ProcessBuilder instead of Runtime.getRuntime.exec() because I need to run the command in a specific directory. I need to use ProcessBuilder.directory().
Ps: The command will exit with 2 after running. It seems that the system can recognize this command. The strange thing is that it has no output after exiting with 2.
Ps: The expected command is /bin/bash -l -c "/Users/ryouyasachi/GettyGradle/build/idea-sandbox/plugins/Getty/classes/python/csi 19f4281 a562db1". I printed the value and it was correct.
Best way to troubleshoot your problem is to construct the command first and pass it to the list. So, instead of doing all this.
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
You should first construct the command
StringBuilder sb = new StringBuilder();
sb.append("/bin/bash -l -c");
sb.append("\""+csi_path+pre_hash+post_hash+"\"");// add whitespace between the varaible, if required.
System.outprintln(sb.toString()); //verify your command here
csi.add(sb.toString());
Also, verify all above variable values.
Thx for #Ravi 's idea!
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"" + csi_path + " " + pre_hash+ " " + post_hash + "\"");
String csi_output = Command.runCommand(project_directory, csi);
The Process has to take each argument separately in order to recognize the command. The tricky part is that, in my desired command
/bin/bash -l -c "/mypath/csi"
"/mypath/csi" needs to be viewed as one single argument by Process.

Some Perl lines won't execute from Java Runtime.getRuntime().exec()

I have a strange behavior when calling a perl script from Java.
The perl code is:
#!/usr/bin/env perl
use warnings;
print "dada\n";
$file = "settings.txt";
open $ds, "<", $file;
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
As you can see, in this code I want to read the file "settings.txt" which contents :
1 : a
2 : b
3 : c
4 : d
And this script works when called from cygwin and the output is :
dada
doudou
1 : a
2 : b
3 : c
4 : d
dodo
But when I call it from Java using the following code:
String line;
String cmd = "perl C:\\Data\\Tests\\match_settings.pl";
try {
Process proc = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println("Line :" + line);
}
in.close();
} catch (IOException a) {
// TODO Auto-generated catch block
a.printStackTrace();
}
Then when the Java function is executed, I get the output:
Line :dada
Line :doudou
Line :dodo
Which means that $line = <$ds> is not well executed, but I don't know why.
Any idea ?
Sorry for the long post, wanted to be as precise as possible.
PS : I know some of you are wondering "Why not read the settings.txt file by Java code himself ?" but that's not the question here ;)
It seems that the folder from which your perl code is executed is not the same when executing from Cygwin and Java. So the perl Script can't find your file.
You should add error checking in your perl code, and verify your current working dir directory.
I would write:
#!/usr/bin/env perl
use warnings;
use Cwd;
my $cwd = cwd();
print "dada\n";
print "In folder: $cwd";
$file = "settings.txt";
open ($ds, "<", $file) || die "Can't open settings.txt. Error code: $!";
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
This will help you debug why, when your script is executed from Java, you don't get the expected results.
You should also redirect stderr to stdout in your Java code, so you will get error lines.

Vowpal Wabbit execute without writing to disk

I wrote a java code to execute Vowpal Wabbit in the following way:
System.out.println("Executing command " + command);
final Runtime r = Runtime.getRuntime();
final Process p = r.exec(command);
System.out.println("waiting for the process");
try (final BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = b.readLine()) != null) {
final T lineResult = textParser.parseLine(line);
parserResultCombiner.addToCombiner(lineResult);
}
}
p.waitFor();
System.out.println("done");
}
where the command is
vw -d input.txt --loss_function=logistic -f model.vw
The disadvantage of this is that it requires writing to disk. After some searching, I learned that vowpal wabbit supports reading data from standard input
example in R
I could not find any example to accomplish this in Java 1.8. Could anyone share one with me?
You need to start vw in daemon mode. This starts a process that listens on the port specified.
$ vw -i model.vw -t --daemon --quiet --port 26542
Once the daemon has started, you can send samples to predict using socket calls
$ echo " abc-example| a b c" | netcat localhost 26542
0.000000 abc-example
$ echo " xyz-example| x y z" | netcat localhost 26542
1.000000 xyz-example
source:
https://github.com/JohnLangford/vowpal_wabbit/wiki/daemon-example
Recently they pushed a java version of the code that interacts with vw using jni
https://github.com/JohnLangford/vowpal_wabbit/tree/master/java

execute commands from another program from a python script

Unable to communicate from a python script with java program.
I have a java program that reads from standard input.
Logic is:
public static void main(String[] args) {
...
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String cmd;
boolean salir = faslse
while (!salir) {
cmd = in.readLine();
JOptionPane.showMessageDialog(null, "run: " + cmd);
//execute cmd
...
System.out.println(result);
System.out.flush();
}
}
I run the program through the console console
java -cp MyProgram.jar package.MyMainClass
And execute commands and get results, and shows the command executed in a dialogue (JOptionPane.showMessageDialog(null, "run: " + cmd); )
I need to call the program from python.
Right now I'm trying with this:
#!/usr/bin/python
import subprocess
p = subprocess.Popen("java -cp MyProgram.jar package.MyMainClass", shell=True, stdout=subprocess.PIPE , stdin=subprocess.PIPE)
print '1- create ok'
p.stdin.write('comand parameter1 parameter2')
print '2- writeComand ok'
p.stdin.flush()
print '3- flush ok'
result = p.stdout.readline() # this line spoils the script
print '4- readline ok'
print result
p.stdin.close()
p.stdout.close()
print 'end'
And the output is
1- create ok
2- writeComand ok
3- flush ok
And does not show the dialog.
however if I run:
#!/usr/bin/python
import subprocess
p = subprocess.Popen("java -cp MyProgram.jar package.MyMainClass", shell=True, stdout=subprocess.PIPE , stdin=subprocess.PIPE)
print '1- create ok'
p.stdin.write('comand parameter1 parameter2')
print '2- writeComand ok'
p.stdin.flush()
print '3- flush ok'
p.stdin.close()
p.stdout.close()
print 'end'
the output is
1- create ok
2- writeComand ok
3- flush ok
end
and show show the dialog.
the line p.stdout.readline() spoils the script, as I can fix this?
Thank you very much any help.
Flush your System.out after printing just one result.
Additionally change your code to do this:
p = subprocess.Popen("java -cp MyProgram.jar package.MyMainClass",
shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write(command1)
p.stdin.flush() # this should trigger the processing in the Java process
result = p.stdout.readline() # this only proceeds if the Java process flushes
p.stdin.write(command2)
p.stdin.flush()
result = p.stdout.readline()
# and afterwards:
p.stdin.close()
p.stdout.close()

Facing some problems while running the Java Program through Shell Script

I have written a shell script for automatic
1) start of hadoop services (namenode,datanode,jobtracker,tasktracker,secondary namenode),
2) dropping all tables from hive
3) again importing all tables in hive from SQL SERVER
And I am calling this shel script from java. Below is the code of Shell Script and Java Code
Shell Script:
export HADOOP_HOME=/home/hadoop/hadoop-0.20.2-cdh3u2/
export HIVE_HOME=/home/hadoop/hive-0.7.1/
export SQOOP_HOME=/home/hadoop/sqoop-1.3.0-cdh3u1/
export MSSQL_CONNECTOR_HOME=/home/hadoop/sqoop-sqlserver-1.0
export HBASE_HOME=/home/hadoop/hbase-0.90.1-cdh3u0
export ZOOKEEPER_HOME=/home/hadoop/zookeeper-3.3.1+10
export SQOOP_CONF_DIR=/home/hadoop/sqoop-1.3.0-cdh3u1/conf/
/home/hadoop/hadoop-0.20.2-cdh3u2/bin/hadoop/start-all.sh
/home/hadoop/hadoop-0.20.2-cdh3u2/bin/hadoop -rmr /user/hadoop/*
/home/hadoop/hive-0.7.1/bin/hive -e 'show tables' > TablesToDelete.txt
while read line1
do
echo 'drop table '$line1
/home/hadoop/hive-0.7.1/bin/hive -e 'drop table '$line1
done < TablesToDelete.txt
while read line
do
echo $line" ------------------------------"
/home/hadoop/sqoop-1.3.0-cdh3u1/bin/sqoop-import --connect 'jdbc:sqlserver://192.168.1.1;username=abcd;password=12345;database=HadoopTest' --table line --hive-table $line --create-hive-table --hive-import -m 1 --hive-drop-import-delims --hive-home /home/hadoop/hive-0.7.1 --verbose
done < /home/hadoop/sqoop-1.3.0-cdh3u1/bin/tables.txt
Java Code:
public class ImportTables
{
public static void main(String arsg[])
{
PrintWriter pw=null;
try
{
Formatter formatter = new Formatter();
String LogFile = "Log-"+ formatter.format("%1$tm%1$td-%1$tH%1$tM%1$tS", new Date());
File f=new File("/home/hadoop/"+LogFile);
FileWriter fw1=null;
pw=new PrintWriter(f);
String cmd = "/home/hadoop/sqoop-1.3.0-cdh3u1/bin/TablesToImport.sh"; // this is the command to execute in the Unix shell
// create a process for the shell
ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
pb.redirectErrorStream(true); // use this to capture messages sent to stderr
Process shell = pb.start();
InputStream shellIn = shell.getInputStream(); // this captures the output from the command
int shellExitStatus = shell.waitFor();
// wait for the shell to finish and get the return code
// at this point you can process the output issued by the command
// for instance, this reads the output and writes it to System.out:
int c;
while ((c = shellIn.read()) != -1)
{
System.out.write(c);
}
// close the stream
shellIn.close();
}
catch(Exception e)
{
e.printStackTrace();
e.printStackTrace(pw);
pw.flush();
System.exit(1);
}
}
}
But as I run the program I see nothiing on the console, and program remains in running mode.
And If I put the following code ion shell script:
/home/hadoop/hive-0.7.1/bin/hive -e 'show tables' > TablesToDelete.txt
while read line1
do
echo 'drop table '$line1
/home/hadoop/hive-0.7.1/bin/hive -e 'drop table '$line1
done < TablesToDelete.txt
Then the output come as:
Cannot find hadoop installation: $HADOOP_HOME must be set or hadoop must be in the path
What is the problem in my program/script? Where and How to set HADOOP_HOME and all that path in my script?
The call to waitFor is a blocking call, just as the name implies. It halts further execution until the process is done. But since your code is also the sink for the process's stdout, the whole thing blocks. Just move the waitFor to after you've processed the script's output.

Categories

Resources