Externe Befehlsausführung mit Swift

Externe Befehlsausführung mit Swift

Wenn Sie "#! / Usr / bin / swift" in den Kopf schreiben

chmod a+x hoge.swift
./hoge.swift #swift hoge.Kann auch mit schnell gestartet werden

Ich wusste, dass es wie ein Skript gestartet werden kann, also übersetzte ich nach dem Studium das Perl-Skript, das ich zur Hand hatte, in schnell. Eine Notiz zu dieser Zeit.

perl

my $status = system "ls hoge/"  #ret-code
my $ret = `ls hoge/ `           #output

Wie soll ich das schnell schreiben? Ich habe es nachgeschlagen.

Einfacher Anruf

Ich habe keine OSX-Apps geschrieben, habe sie also nicht verwendet, aber unter NSTask Ich denke ich kann es schaffen. Sie können die Ausgabe externer Befehle mit task.standardOutput (NSPipe) empfangen. Wenn Sie das aktuelle Verzeichnis angeben und ausführen möchten, setzen Sie es auf "task.currentDirectoryPath".

func stdOutOfCommand(cmd: String, arguments args: [String], currentDirPath currentDir: String? = nil) -> String {
    let task: NSTask = NSTask()
    task.launchPath = cmd
    task.arguments = args
    if currentDir != nil { task.currentDirectoryPath = currentDir! }
    let pipe: NSPipe = NSPipe()
    task.standardOutput = pipe
    task.launch()
    let out: NSData = pipe.fileHandleForReading.readDataToEndOfFile()
    let outStr: String? = NSString(data: out, encoding: NSUTF8StringEncoding) as? String
    return outStr == nil ? "" : outStr!
}

var ret = stdOutOfCommand("/bin/ls", arguments: ["hoge/"])

Interaktiv

Verwenden Sie im interaktiven Format (erfordert Eingabe) waitForDataInBackgroundAndNotify (), um zu benachrichtigen, dass es sich um eine Hintergrundwartezeit handelt. NSNotificationCenter muss "NSFileHandleDataAvailableNotification" erhalten.

Wenn Sie warten möchten, bis die Aufgabe beendet ist, warten Sie mit task.waitUntilExit (). Der Endstatus kann mit task.terminationStatus abgerufen werden.

Im folgenden Beispiel wird die Eingabe mit "NSFileHandle.fileHandleWithStandardInput ()" gesteuert.

func printFlush(message: String) {
    print(message, terminator: "")
    fflush(__stdoutp)
}
func scriptWithCmd(cmd: String, arguments args: [String], currentDirPath currentDir: String? = nil) -> Int32 {
    //set task
    let input: NSFileHandle = NSFileHandle.fileHandleWithStandardInput()
    let inPipe: NSPipe = NSPipe()
    let outPipe: NSPipe = NSPipe()
    let task: NSTask = NSTask()
    task.launchPath = cmd
    task.arguments = args
    if currentDir != nil { task.currentDirectoryPath = currentDir! }
    task.standardOutput = outPipe
    task.standardInput = inPipe
    task.launch()
    
    //notification
    input.waitForDataInBackgroundAndNotify()
    outPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
    NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification, object: input, queue: nil,
        usingBlock : { (notification: NSNotification!) in
            let inData: NSData = input.availableData
            if inData.length > 0 {
                inPipe.fileHandleForWriting.writeData(inData)
                input.waitForDataInBackgroundAndNotify()
            } else {
                inPipe.fileHandleForWriting.closeFile()
            }
        }
    )
    NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification, object: outPipe.fileHandleForReading, queue: nil,
        usingBlock:  { (notification: NSNotification!) in
            let outData: NSData = outPipe.fileHandleForReading.availableData
            if let outStr: NSString = NSString(data: outData, encoding: NSUTF8StringEncoding) {
                printFlush(outStr as String)
            }
            outPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
        }
    )
    
    task.waitUntilExit()
    return task.terminationStatus
}

Einfaches Memo zum Aufrufen externer Befehle in anderen Sprachen

Die, über die ich vorher ein wenig recherchiert habe

Perl

Es gibt auch exec (), aber es kommt nicht zurück, also benutze system (). Zurück Zitat bequem.

my $status = system "ls hoge/"  #ret-code
my $ret = `ls hoge/ `           #output

C

Zuvor war Perl zu langsam, daher ein Hinweis, als ich versuchte, verschiedene Dinge mit C / C ++ zu tun

#include <stdlib.h>
	int ret = system("ls hoge/");

Mit POSIX können Sie "popen / pclose" verwenden.

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#define BUF 256
int main (void) {
	FILE *fp;
	char buf[BUF];
	char *cmd = "/bin/ls hoge/";
	
	if ((fp=popen(cmd,"r")) == NULL) {
		err(EXIT_FAILURE, "%s", cmd);
	}
	while(fgets(buf, BUF, fp) != NULL) {
		fputs(buf, stdout);
	}
	pclose(fp);

	return 0;
}

Da popen nicht gleichzeitig ein- und ausgeben kann, müssen um "pipe ()", "dup ()", "fork ()" und "exec * ()" verwendet werden.

Referenz

C++

PStreams (POSIX) scheint verwendbar zu sein

Java

Es scheint ProcessBuilder zu verwenden. Können Befehle, die die Shell direkt interpretiert, direkt ausgeführt werden?

Referenz

JavaScript(Node.js)

execSync = require("child_process").execSync;
result = execSync("ls");

Referenz

Recommended Posts

Externe Befehlsausführung mit Swift
Erste Schritte mit Swift
Beginnend mit Swift Swift UI
Ändern Sie Wordpress siteurl mit dem Befehl
Vergleichen Sie Java 8 Optional mit Swift
Ausführen des Postgresql-Kopierbefehls mit Spalteninformationen in Java
Führen Sie gepackten Java-Code mit Befehlen aus
Erstellen Sie eine Befehlszeilen-App mit maven
Schnelles Anfänger-Xcode-Debugging-Memo
Erstellen Sie ein Maven-Projekt mit Befehlen