将包含变音符号的密码作为 Swift 中的参数传递给 Process 时出现问题
Problems when passing password containing umlauts to Process as argument in Swift
所以我尝试使用来自 Swift 的 sudo 执行命令,使用以下代码(建议 here:
func doTask(_ password:String) {
let taskOne = Process()
taskOne.launchPath = "/bin/echo"
taskOne.arguments = [password]
let taskTwo = Process()
taskTwo.launchPath = "/usr/bin/sudo"
taskTwo.arguments = ["-S", "/usr/bin/xattr", "-d", "-r", "com.test.exemple", " /Desktop/file.extension"]
//taskTwo.arguments = ["-S", "/usr/bin/touch", "/tmp/foo.bar.baz"]
let pipeBetween:Pipe = Pipe()
taskOne.standardOutput = pipeBetween
taskTwo.standardInput = pipeBetween
let pipeToMe = Pipe()
taskTwo.standardOutput = pipeToMe
taskTwo.standardError = pipeToMe
taskOne.launch()
taskTwo.launch()
let data = pipeToMe.fileHandleForReading.readDataToEndOfFile()
let output : String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
print(output)
}
它适用于“test”、“password#123”等密码。但是当我尝试使用包含元音符号(例如“ä”、“ü”或“ö”)的密码时,它却无法正常工作工作。有什么想法吗?
我不确定为什么另一个问题的答案通过 echo
... 似乎引入了不必要的并发症和未知数。
以下更直接的方法已经过测试并且有效:
import Foundation
let password = "äëïöü"
let passwordWithNewline = password + "\n"
let sudo = Process()
sudo.launchPath = "/usr/bin/sudo"
sudo.arguments = ["-S", "/bin/ls"]
let sudoIn = Pipe()
let sudoOut = Pipe()
sudo.standardOutput = sudoOut
sudo.standardError = sudoOut
sudo.standardInput = sudoIn
sudo.launch()
// Show the output as it is produced
sudoOut.fileHandleForReading.readabilityHandler = { fileHandle in
let data = fileHandle.availableData
if (data.count == 0) { return }
print("read \(data.count)")
print("\(String(bytes: data, encoding: .utf8) ?? "<UTF8 conversion failed>")")
}
// Write the password
sudoIn.fileHandleForWriting.write(passwordWithNewline.data(using: .utf8)!)
// Close the file handle after writing the password; avoids a
// hang for incorrect password.
try? sudoIn.fileHandleForWriting.close()
// Make sure we don't disappear while output is still being produced.
sudo.waitUntilExit()
print("Process did exit")
关键是密码后必须加换行。 (我想在某些方面 echo
只是一种过于复杂的方法!)
所以我尝试使用来自 Swift 的 sudo 执行命令,使用以下代码(建议 here:
func doTask(_ password:String) {
let taskOne = Process()
taskOne.launchPath = "/bin/echo"
taskOne.arguments = [password]
let taskTwo = Process()
taskTwo.launchPath = "/usr/bin/sudo"
taskTwo.arguments = ["-S", "/usr/bin/xattr", "-d", "-r", "com.test.exemple", " /Desktop/file.extension"]
//taskTwo.arguments = ["-S", "/usr/bin/touch", "/tmp/foo.bar.baz"]
let pipeBetween:Pipe = Pipe()
taskOne.standardOutput = pipeBetween
taskTwo.standardInput = pipeBetween
let pipeToMe = Pipe()
taskTwo.standardOutput = pipeToMe
taskTwo.standardError = pipeToMe
taskOne.launch()
taskTwo.launch()
let data = pipeToMe.fileHandleForReading.readDataToEndOfFile()
let output : String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
print(output)
}
它适用于“test”、“password#123”等密码。但是当我尝试使用包含元音符号(例如“ä”、“ü”或“ö”)的密码时,它却无法正常工作工作。有什么想法吗?
我不确定为什么另一个问题的答案通过 echo
... 似乎引入了不必要的并发症和未知数。
以下更直接的方法已经过测试并且有效:
import Foundation
let password = "äëïöü"
let passwordWithNewline = password + "\n"
let sudo = Process()
sudo.launchPath = "/usr/bin/sudo"
sudo.arguments = ["-S", "/bin/ls"]
let sudoIn = Pipe()
let sudoOut = Pipe()
sudo.standardOutput = sudoOut
sudo.standardError = sudoOut
sudo.standardInput = sudoIn
sudo.launch()
// Show the output as it is produced
sudoOut.fileHandleForReading.readabilityHandler = { fileHandle in
let data = fileHandle.availableData
if (data.count == 0) { return }
print("read \(data.count)")
print("\(String(bytes: data, encoding: .utf8) ?? "<UTF8 conversion failed>")")
}
// Write the password
sudoIn.fileHandleForWriting.write(passwordWithNewline.data(using: .utf8)!)
// Close the file handle after writing the password; avoids a
// hang for incorrect password.
try? sudoIn.fileHandleForWriting.close()
// Make sure we don't disappear while output is still being produced.
sudo.waitUntilExit()
print("Process did exit")
关键是密码后必须加换行。 (我想在某些方面 echo
只是一种过于复杂的方法!)