Swift wrapper for libssh2 with static build
brew install openssl zlib libssh2
let ssh = try await SSH2.connect(
"example.com",
port: 22,
banner: "SSH-2.0-libssh2_Demo"
)
Password authentication:
try await ssh.auth(
"root",
SSH2AuthMethod.password("password")
)
Private key authentication:
let key = try String(
contentsOfFile: "/Users/example/.ssh/id_ed25519",
encoding: .utf8
)
try await ssh.auth(
"root",
SSH2AuthMethod.privateKey(key, "passphrase")
)
Ask for passphrase if needed:
var auth = SSH2AuthMethod.privateKey("...")
while true {
do {
try await ssh.auth(username, auth)
break
} catch {
switch error {
case SSH2Error.authFailed(-16, _):
let passphrase = requestPassphrase()
auth = .privateKey(key, passphrase)
default:
throw error
}
}
}
Basic command execution:
let channel = try await ssh.exec("ls -la")
let (stdout, stderr) = try await channel.readAll()
Writing data to the command stdin:
let script = "date"
let data = script.data(using: .utf8)!
let channel = try await ssh.exec("/bin/sh -s")
try await channel.writeAll(data)
Writing from file to the command stdin:
let stdin = Pipe()
let channel = try await ssh.exec("/bin/sh -s")
try await channel.writeAll(stdin.fileHandleForReading)
Reading data from command with handlers:
try await channel.readAll(
stdoutHandler: {
if let text = String(data: $0, encoding: .utf8) {
print(text, terminator: "")
}
},
stderrHandler: {
if let text = String(data: $0, encoding: .utf8) {
print(text, terminator: "")
}
}
)
Reading data from command to string:
let (stdout, stderr) = try await channel.readAll()
You may cancel task any time:
let task = Task {
let (stdout, stderr) = try await channel.readAll()
}
task.cancel()
Executed process will keep running on the server side.