5

Is there a good description of swift system command? For example, this code

    let x = system("ls -l `which which`")
    println(x)

produces -rwxr-xr-x 1 root wheel 14496 Aug 30 04:29 /usr/bin/which

0

I would like to separate the output from the return code

Lanny Rosicky
  • 603
  • 1
  • 6
  • 9

1 Answers1

9

system() is not a Swift command but a BSD library function. You get the documentation with "man system" in a Terminal Window:

The system() function hands the argument command to the command interpreter sh(1). The calling process waits for the shell to finish executing the command, ignoring SIGINT and SIGQUIT, and blocking SIGCHLD.

The output of the "ls" command is just written to the standard output and not to any Swift variable.

If you need more control then you have to use NSTask from the Foundation framework. Here is a simple example:

let task = NSTask()
task.launchPath = "/bin/sh"
task.arguments = ["-c", "ls -l `which which`"]

let pipe = NSPipe()
task.standardOutput = pipe
task.launch()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
if let output = NSString(data: data, encoding: NSUTF8StringEncoding) {
    println(output)
}

task.waitUntilExit()
let status = task.terminationStatus
println(status)

Executing the command via the shell "/bin/sh -c command ..." is necessary here because of the "back tick" argument. Generally, it is better to invoke the commands directly, for example:

task.launchPath = "/bin/ls"
task.arguments = ["-l", "/tmp"]
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • If system is not a Swift command, how come in runs from Swift? This is not capricious comment, it is a question on Swift's semantics.The code you present of corse works - I had tried it before. I was just wondering why I could not/should not use system() instead. If you note in my "code, variable x IS assigned the output of both ls and $? – Lanny Rosicky Oct 17 '14 at 07:18
  • @LannyRosicky: All (well, most) library functions are available to Swift as part of the Darwin module which is included e.g. by Foundation. – Martin R Oct 17 '14 at 07:23
  • BTW, the example code gives "Bound value in a conditional binding mut bo of Optional type " – Lanny Rosicky Oct 17 '14 at 07:30
  • @LannyRosicky: Try `println("x=\(x)")` to convince yourself that `x` is only assigned the exit code. The output of the command is written directly to the console. – I have (again) tested the above code with Xcode 6.1 GM Seed 2 where it compiles and runs as expected. – Martin R Oct 17 '14 at 07:34
  • Yes. x does contain only $?. Your example works in my version 6.0 (6A279r) only if I forgo the "if" . I will upgrade it. And I will read on Darwin module to stop myself from putting my foot in ... – Lanny Rosicky Oct 17 '14 at 07:55
  • @LannyRosicky: I have tested the code again with the current Xcode 6.1. Please let me know if you need more information. – Martin R Nov 15 '14 at 10:05
  • FYI, 'NSTask' has been renamed to 'Process' now. – Zigii Wong May 13 '19 at 03:03