• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

224
Vistas
Abriendo un nuevo archivo de dispositivo pseudo-terminal en macOS con swift

Estoy tratando de mantener un shell ( bash / zsh / etc ) en ejecución mediante el uso de Process de la biblioteca Foundation.

Sé cómo usar Pipe para entrada/salida/error estándar para otros ejecutables de línea de comando, pero parece que los programas de shell requieren que el archivo de entrada/salida/error estándar sea un archivo de dispositivo terminal.

Parece que estos son los archivos llamados /dev/ttys<3 digit number> que se crean para cada nueva instancia de shell. ¿Cómo puedo crear estos archivos yo mismo y usarlos rápidamente?

over 3 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

SOLUCIÓN:

Así que esto resultó ser mucho más fácil de lo que pensé que sería. Estos son los pasos necesarios para crear un par de objetos FileHandle de pseudo-terminal maestro y esclavo:

  1. Importe el módulo Darwin .
  2. Llame a posix_openpt(int oflag) para obtener un descriptor de archivo para un dispositivo pseudo-terminal maestro disponible.
  3. Llame a grantpt(int filedes) para establecer la propiedad del dispositivo pseudo-terminal esclavo correspondiente.
  4. Llame a unlockpt(int filedes) para desbloquear el dispositivo pseudo-terminal esclavo.
  5. Llame a ptsname(int filedes) para obtener la ruta al dispositivo pseudo-terminal esclavo.
  6. Cree objetos FileHandle utilizando el descriptor de archivo del paso 2 y la ruta del paso 5.

En los pasos 3 a 5, filedes es el descriptor de archivo devuelto por la llamada a posix_openpt(int oflag) del paso 1. Use O_RDRW para el parámetro oflag en el paso 1 para obtener permisos de lectura y escritura en el archivo del dispositivo pseudo-terminal maestro.

Código de ejemplo en el que mantenemos activa una sesión de bash y hacemos que ejecute el comando tty :

 import Foundation import Darwin class A: NSObject { var task: Process? var slaveFile: FileHandle? var masterFile: FileHandle? override init() { self.task = Process() var masterFD: Int32 = 0 masterFD = posix_openpt(O_RDWR) grantpt(masterFD) unlockpt(masterFD) self.masterFile = FileHandle.init(fileDescriptor: masterFD) let slavePath = String.init(cString: ptsname(masterFD)) self.slaveFile = FileHandle.init(forUpdatingAtPath: slavePath) self.task!.executableURL = URL(fileURLWithPath: "/bin/bash") self.task!.arguments = ["-i"] self.task!.standardOutput = slaveFile self.task!.standardInput = slaveFile self.task!.standardError = slaveFile } func run() { DispatchQueue.global(qos: .userInitiated).async { [weak self] in guard let self = self else { return } do { try self.task!.run() } catch { print("Something went wrong.\n") } } let data = self.masterFile!.availableData let strData = String(data: data, encoding: String.Encoding.utf8)! print("Output: "+strData) self.masterFile!.write("tty\u{0D}".data(using: String.Encoding.utf8)!) sleep(1) let data1 = self.masterFile!.availableData let strData1 = String(data: data1, encoding: String.Encoding.utf8)! print("Output: "+strData1) } } let a = A() a.run()
over 3 years ago · Santiago Trujillo Denunciar

0

Una respuesta aún más simple que es compatible con Playground.

 import PlaygroundSupport import Foundation import Darwin // use socat to create psudo echo device // socat -d -d -x pty,raw,nonblock,ispeed=115200,echo=0,link=/dev/ttys000 EXEC:/bin/cat print("Started:\n") var masterFile: FileHandle? var masterFD: Int32 = 0 masterFD = open("/dev/ttys000",O_RDWR|O_NONBLOCK) grantpt(masterFD) unlockpt(masterFD) masterFile = FileHandle.init(fileDescriptor: masterFD) masterFile!.write("tty\u{0D}".data(using: String.Encoding.utf8)!) sleep(1) let data1 = masterFile!.availableData let strData1 = String(data: data1, encoding: String.Encoding.utf8)! print("Output: "+strData1)
over 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda