Si vous écrivez #! / Usr / bin / swift dans la tête
chmod a+x hoge.swift
./hoge.swift #swift hoge.Peut également être démarré avec swift
Je savais que cela pouvait être lancé comme un script, donc après avoir étudié, j'ai traduit le script perl que j'avais sous la main en swift. Une note à ce moment-là.
perl
my $status = system "ls hoge/"  #ret-code
my $ret = `ls hoge/ `           #output
Comment dois-je écrire cela en swift? Je l'ai cherché.
Je n'ai écrit aucune application OSX, donc je ne les ai pas utilisées, mais sur NSTask Je pense que je peux le faire.
Vous pouvez recevoir la sortie des commandes externes avec task.standardOutput (NSPipe).
Si vous souhaitez spécifier le répertoire courant et l'exécuter, définissez-le sur 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/"])
Dans le format interactif (nécessite une entrée), utilisez waitForDataInBackgroundAndNotify () pour notifier qu'il s'agit d'une attente en arrière-plan.
NSNotificationCenter doit recevoir «NSFileHandleDataAvailableNotification».
Si vous voulez attendre la fin de la tâche, attendez avec task.waitUntilExit ().
Le statut de fin peut être obtenu avec task.terminationStatus.
Dans l'exemple ci-dessous, l'entrée est contrôlée à l'aide de NSFileHandle.fileHandleWithStandardInput ().
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
}
Celui sur lequel j'ai fait une petite recherche avant
Perl
Il y a aussi ʻexec () , mais il ne revient pas, alors utilisez system () `.
Retour de devis pratique.
my $status = system "ls hoge/"  #ret-code
my $ret = `ls hoge/ `           #output
C
Auparavant, perl était trop lent, donc une note lorsque j'essayais de faire diverses choses avec C / C ++
#include <stdlib.h>
	int ret = system("ls hoge/");
Avec POSIX, vous pouvez utiliser popen / pclose.
#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;
}
Puisque popen ne peut pas entrer et sortir en même temps, il est nécessaire d'utiliser autour de pipe (), dup (), fork (), ʻexec * () `.
C++
PStreams (POSIX) semble être utilisable
Java
Il semble utiliser ProcessBuilder, Les commandes que le shell interprète directement peuvent-elles être exécutées directement?
référence
JavaScript(Node.js)
execSync = require("child_process").execSync;
result = execSync("ls");
Recommended Posts