Frage

Alle,

Ich hatte ursprünglich ein Shell -Skript, das SQLllloader (Oracles Data Upload -Tool) bezeichnete.

Das Problem war, dass SQLlloader ein einfaches Textkennwort als Eingabe nimmt. Deshalb habe ich mich entschlossen, eine Java -Anwendung zu erstellen, um SQLlloader intern ein entschlüsseltes Passwort in die Befehlszeichenfolge aufzurufen.

z.B

SQLLDR -Benutzer/Pass@dbserver control = ../sqlLoader.ctl log = sqllloader.log data = mydata.csv

Also mit meinem Java -Wrapper wurde es dies in meinem Shell -Skript

java -jar sqlloader.jar sqlloader.ctl mydata.csv

Ein neues Problem, das sich jedoch entwickelte, als sich SQLLOADER beschwert hatte, dass keine Datei geladen werden musste. Nach einigen Kopfkratzern wurde festgestellt, dass ein nachfolgender Befehl in meinem Shell -Skript ausgeführt zu werden schien, während meine Java -Anwendung noch ausgeführt wurde. Deshalb benahm es sich asynchron.

Der nächste Befehl bestand darin, die Eingabedatei zu verschieben, die SQLlloader verwendet hatte, bevor er die Möglichkeit erhalten konnte, sie zu verwenden. Also habe ich in 20 Sekunden einen Schlafkommando gestellt, um meine Java -Bewerbungszeit zum Laufen zu geben.

java -jar sqlloader.jar sqlloader.ctl mydata.csv
echo $?
sleep 20
if [ $? -ne 0 ]
    then
        echo "SQLLoader failed during execution, please check the log : " 
        mv mydata.csv

else
    echo "SQLLoader successfully processed file : "
    mv mydata.csv
fi

Weiß jemand, warum sich Unix auf diese Weise verhält?

Dies ist mein Java -Code:

    Runtime Rt;
Process Prc;
    Prc = Rt.exec("sqlldr user/decryptedpass@DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv);
system.exit(0);

Ich habe die Laufzeitklasse über etwas darüber überprüft, ob es asynchron ist, konnte aber nichts finden

http://docs.oracle.com/javase/7/docs/api/java/lang/runtime.html

Irgendwelche Theorien oder Vorschläge?

Vielen Dank

War es hilfreich?

Lösung

Ja. Wenn Sie sich Runtime.exec erneut ansehen, wird angegeben, dass ein neuer Prozess in der angegebenen Umgebung gestartet wird (z. B. unabhängig von der aktuellen "Umgebung" oder wie Sie es asynchron ausdrücken). Du solltest benutzen ProcessBuilder a Verfahren Und dann auf diesen Prozess, um vor dem Aufruf von System.exit zu beenden - was sicherlich nicht obligatorisch ist. Etwas wie das

public static void main(String[] args) {
    // String command = "/usr/bin/sleep 5";
    List<String> command = new ArrayList<String>();
    command.add("c:/cygwin/bin/sleep");
    command.add("5");
    ProcessBuilder pb = new ProcessBuilder(command);
    BufferedReader is = null;
    try {
        System.out.println("Starting command " + command);
        Process p = pb.start();

        int ret = p.waitFor();
        is = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = is.readLine()) != null) {
            System.out.println(line);
        }
        if (ret == 0) {
            System.out.println("Command has completed.");
            System.exit(ret);
        } else {
            System.out.println("Command completed with return code " + ret);
            System.exit(ret);
        }
    } catch (Exception e) {
        System.out.println("Caught Exception " + e.getMessage()
                + " running command " + command);
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
    System.out.println("COMMAND FAILED");
    System.exit(1);
}

Andere Tipps

Sie müssen auf den Abschluss des Prozesses warten. Sie sollten auch alle Ausgaben lesen (STDOut und sterr) aus dem Prozess, den Sie beginnen.

Wenn Sie Exit () nach exec () anrufen, wird Java genau das tun - sofort Exit.

Hier ist ein Artikel, der rundime.exec Fallstricke erklärt: http://www.javaorld.com/javarld/jw-12-2000/jw-1229-traps.html?page=4 (Betrachten Sie auch die anderen Seiten).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top