Ik probeer een aantal Linux-opdrachten uit Java uit te voeren met behulp van omleiding (& GT; & amp;) en pijpen (|). Hoe kan Java zich aanroepen csh
of bash
-opdrachten?
Ik heb geprobeerd dit te gebruiken:
Process p = Runtime.getRuntime().exec("shell command");
Maar het is niet compatibel met omleidingen of leidingen.
Antwoord 1, Autoriteit 100%
Exec voert geen opdracht uit in uw shell
Probeer
Process p = Runtime.getRuntime().exec(new String[]{"csh","-c","cat /home/narek/pk.txt"});
in plaats daarvan.
Bewerken ::
Ik heb geen csh op mijn systeem, dus ik heb in plaats daarvan bash gebruikt. Het volgende werkte voor mij
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","ls /home/XXX"});
Antwoord 2, Autoriteit 31%
Gebruik ProcessBuilder om opdrachten en argumenten in plaats van spaties te scheiden. Dit zou moeten werken, ongeacht de gebruikte schaal:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(final String[] args) throws IOException, InterruptedException {
//Build command
List<String> commands = new ArrayList<String>();
commands.add("/bin/cat");
//Add arguments
commands.add("/home/narek/pk.txt");
System.out.println(commands);
//Run macro on target
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File("/home/narek"));
pb.redirectErrorStream(true);
Process process = pb.start();
//Read output
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null, previous = null;
while ((line = br.readLine()) != null)
if (!line.equals(previous)) {
previous = line;
out.append(line).append('\n');
System.out.println(line);
}
//Check result
if (process.waitFor() == 0) {
System.out.println("Success!");
System.exit(0);
}
//Abnormal termination: Log command parameters and output and throw ExecutionException
System.err.println(commands);
System.err.println(out.toString());
System.exit(1);
}
}
Antwoord 3, Autoriteit 15%
Gebouw op het voorbeeld van @ Tim om een zelfstandige methode te maken:
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Shell {
/** Returns null if it failed for some reason.
*/
public static ArrayList<String> command(final String cmdline,
final String directory) {
try {
Process process =
new ProcessBuilder(new String[] {"bash", "-c", cmdline})
.redirectErrorStream(true)
.directory(new File(directory))
.start();
ArrayList<String> output = new ArrayList<String>();
BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = null;
while ( (line = br.readLine()) != null )
output.add(line);
//There should really be a timeout here.
if (0 != process.waitFor())
return null;
return output;
} catch (Exception e) {
//Warning: doing this is no good in high quality applications.
//Instead, present appropriate error messages to the user.
//But it's perfectly fine for prototyping.
return null;
}
}
public static void main(String[] args) {
test("which bash");
test("find . -type f -printf '%T@\\\\t%p\\\\n' "
+ "| sort -n | cut -f 2- | "
+ "sed -e 's/ /\\\\\\\\ /g' | xargs ls -halt");
}
static void test(String cmdline) {
ArrayList<String> output = command(cmdline, ".");
if (null == output)
System.out.println("\n\n\t\tCOMMAND FAILED: " + cmdline);
else
for (String line : output)
System.out.println(line);
}
}
(Het testvoorbeeld is een opdracht die alle bestanden in een map en zijn submappen recursief, in chronologische volgorde weergeeft.)
Trouwens, als iemand me kan vertellen waarom ik vier en acht backslashes nodig heb, in plaats van twee en vier, kan ik iets leren. Er is nog een niveau van niet-ontsnappen dat gebeurt dan wat ik tel.
Bewerken: Ik heb net dezelfde code op Linux geprobeerd, en daar blijkt dat ik de helft minder backslashes nodig heb in het testcommando! (Dat wil zeggen: het verwachte aantal van twee en vier.) Nu is het niet langer alleen maar raar, het is een draagbaarheidsprobleem.