Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting input from stdin in a Cocoa command-line app's sub process

I have a command-line app A, and in A I execute an executable script B, in B I'm expecting an input from stdin.

I wrote a demo, implementing A in Swift, using Foundation's Process api, finding that B, no matter implemented in whatever language, cannot get user input from stdin.

Code:

// `A`'s main.swift
import Foundation
let process = Process()
process.launchPath = PATH_TO_SCRIPT_B
process.launch()
process.waitUntilExit()

// `B`
#!/usr/bin/swift 
print("intpu something")
let input = readLine()
print("input: \(input)")

I did not set the process's input since according to the doc:

If this method isn’t used, the standard input is inherited from the process that created the receiver.


UPDATE:

A is an executable package created using Swift Package Manager. I used swift package generate-xcodeproj to generate an Xcode project file. I confirmed that if I run the executable built using swift build or xcodebuild in a shell, the problem with getting input from stdin from B arose. However if I run it directly inside Xcode, by pressing command + R inside Xcode, then it worked. So if I understand the difference between running an executable in a shell and Xcode, I can probably make everything work.

like image 209
axl411 Avatar asked Nov 08 '22 05:11

axl411


1 Answers

func task() {
  print("input here")
  let x = input()
  print ("inputed:" + x)
}

func input() -> String {
  let keyboard = FileHandle.standardInput
  let inputData = keyboard.availableData
  let strData = String(data: inputData, encoding: .utf8)!

  let string = strData.trimmingCharacters(in: .newlines)
  return string
}

task()

Hope it helps

like image 133
PhilCai Avatar answered Nov 15 '22 04:11

PhilCai