Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

277
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 4 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 4 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 4 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 Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda