If you write #! / Usr / bin / swift in your head
chmod a+x hoge.swift
./hoge.swift #swift hoge.Can also be started with swift
I knew that it could be started like a script, so after studying, I translated the perl script I had at hand into swift. A memo at that time.
perl
my $status = system "ls hoge/" #ret-code
my $ret = `ls hoge/ ` #output
How should I write this in swift? I looked it up.
I haven't written any OSX apps, so I haven't used them, but at NSTask I think I can do it.
You can receive the output of external commands with task.standardOutput (NSPipe).
If you want to specify the current directory and execute it, set it to 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/"])
In the case of interactive (request input) format, use waitForDataInBackgroundAndNotify () to notify that it is a background wait.
NSNotificationCenter needs to receive NSFileHandleDataAvailableNotification.
If you want to wait until the task finishes, wait with task.waitUntilExit ().
The exit status can be obtained with task.terminationStatus.
In the example below, the input is controlled using 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
}
The one I did a little research on before
Perl
There is also ʻexec (), but it doesn't come back, so use system ()`.
Back quote convenient.
my $status = system "ls hoge/" #ret-code
my $ret = `ls hoge/ ` #output
C
It's too late with perl before, so a memo when I was trying to do various things with C / C ++
#include <stdlib.h>
int ret = system("ls hoge/");
With POSIX, you can use 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;
}
I / O cannot be done at the same time with popen, so you need to use around pipe (), dup (), fork (), ʻexec * () `.
C++
PStreams (POSIX) seems to be usable
Java
It seems to use ProcessBuilder, Can commands that the shell interprets directly be executed directly?
reference
-Java External Process Start Memo (Hishidama's Java Process Memo) -Redirect with Process Builder of Java SE 7
JavaScript(Node.js)
execSync = require("child_process").execSync;
result = execSync("ls");
Recommended Posts