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