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