Archivos y Jobs

Bibliotecas, IFS, Library List, tipos de objetos, archivos físicos y lógicos, subsistemas, gestión de trabajos, colas y spool.

Modelo tradicional: Bibliotecas (Libraries)

En IBM i, el equivalente a una "carpeta" es una Biblioteca (Library), pero con una diferencia crucial: las bibliotecas no se anidan (no podés tener una biblioteca dentro de otra, excepto QSYS que las contiene todas).

QSYSbiblioteca del sistema, las contiene a todas
QGPLbiblioteca general del usuario
QTEMPtemporal, se borra al cerrar sesión
MIAPP_PRODtu aplicación, producción
MIAPP_DEVtu aplicación, desarrollo

Para referenciar un objeto usás el nombre calificado: BIBLIOTECA/OBJETO

Bibliotecas del sistema importantes:

QSYS

Biblioteca maestra, contiene todas las demás y objetos del sistema

QGPL

General Purpose Library, disponible para todos

QTEMP

Temporal, se crea por cada sesión y se destruye al finalizar

QSYS2

Funciones SQL y vistas del sistema

QUSRSYS

Objetos creados por el sistema para los usuarios

QRECOVERY

Objetos de recuperación del sistema

Comandos para bibliotecas

CL — Gestión de Bibliotecas
CRTLIB LIB(MIAPP)           Crear una biblioteca
DLTLIB LIB(MIAPP)           Eliminar una biblioteca
WRKLIB LIB(MI*)             Ver bibliotecas que coincidan con patrón
DSPLIB LIB(MIAPP)           Ver contenido de una biblioteca
WRKOBJ OBJ(MIAPP/*ALL)      Ver todos los objetos de una biblioteca

Library List

Cada trabajo tiene una library list que determina dónde buscar objetos, similar al PATH de Linux/Windows. Cuando ejecutás un programa sin calificar (CALL MIPROG), el sistema busca recorriendo la library list de arriba a abajo.

Partes de la Library List

La library list se compone de tres secciones, evaluadas en este orden:

System portion

Bibliotecas del sistema (QSYS, QSYS2, QHLPSYS, QUSRSYS). Configuradas por el administrador, no se modifican habitualmente.

Product libraries

Bibliotecas agregadas automáticamente por productos IBM (ej: QRPGLE para compilar RPG). Temporales y contextuales.

User portion (Current + User libs)

Las bibliotecas que vos controlás. Incluye la Current Library y las User Libraries. Aquí ponés tus bibliotecas de aplicación.

Comandos para manipular la Library List

CL — Library List
DSPLIBL                     Mostrar la library list actual
ADDLIBLE LIB(MIAPP)        Agregar biblioteca a la user portion
RMVLIBLE LIB(MIAPP)        Quitar biblioteca de la library list
CHGLIBL LIBL(MIAPP QGPL)   Reemplazar toda la user portion
CHGCURLIB CURLIB(MIAPP)     Cambiar la Current Library
EDTLIBL                     Editor interactivo de la library list
Cuidado: Si un objeto existe en dos bibliotecas de tu library list, se usará el de la primera que aparezca. Esto es intencional y se aprovecha para tener entornos separados (dev/prod) con el mismo nombre de programa pero en distintas bibliotecas.
Comparación x86: Es como tener un PATHpor sesión que podés modificar en caliente. Si en Linux tenés /usr/local/bin:/usr/bin, en IBM i tendrías MIAPP_DEV:MIAPP_COMMON:QGPL.

Tipos de objetos

Todo en IBM i es un objeto. Cada objeto tiene un tipo que determina qué operaciones se pueden hacer con él. Esto es mucho más estricto que en x86, donde un archivo es solo una secuencia de bytes.

TipoNombreEquivalente x86
*PGMProgramaEjecutable binario (.exe, ELF)
*SRVPGMService ProgramShared library (.so, .dll)
*MODULEMóduloObjeto compilado (.o, .obj)
*FILEArchivoTabla de BD / archivo de datos
*DTAARAData AreaVariable global persistente / config
*DTAQData QueueCola de mensajes (message queue)
*USRSPCUser SpaceBloque de memoria compartida
*MSGQMessage QueueCola de mensajes del sistema
*JOBDJob DescriptionPerfil de ejecución / systemd unit
*SBSDSubsystem DescriptionDefinición de servicio / daemon config
*OUTQOutput QueueCola de impresión
*CMDCommandComando del shell (con validación)
*BNDDIRBinding DirectoryCatálogo de linkeo (ld search path)
*USRPRFUser ProfileCuenta de usuario (/etc/passwd)

Comandos para trabajar con objetos

CL — Objetos
WRKOBJ OBJ(MILIB/*ALL)        Ver todos los objetos de una biblioteca
WRKOBJ OBJ(MILIB/*ALL) OBJTYPE(*PGM)    Solo programas
DSPOBJD OBJ(MILIB/MIPROG) OBJTYPE(*PGM)  Detalle de un objeto
MOVOBJ OBJ(MIPROG) OBJTYPE(*PGM) TOLIB(OTRA)  Mover objeto
CRTDUPOBJ                    Duplicar un objeto entre bibliotecas
RNMOBJ OBJ(VIEJO) OBJTYPE(*PGM) NEWOBJ(NUEVO)  Renombrar
Comparación x86: En Linux, un archivo es una secuencia de bytes sin tipo intrínseco. El SO no sabe si miprog es un ejecutable hasta que lo abrís. En IBM i, el sistema sabe que un *PGM es un programa y no te deja tratarlo como un archivo de datos. Esta tipificación estricta previene errores y mejora la seguridad.

Archivos físicos y lógicos

En IBM i, los datos se almacenan tradicionalmente en Physical Files (PF) y se acceden a través de Logical Files (LF). Hoy en día se usan también tablas y vistas SQL, pero los conceptos PF/LF siguen siendo fundamentales.

Physical File (PF)

  • Contiene los datos reales (registros)
  • Definido por DDS (Data Description Specifications) o SQL CREATE TABLE
  • Equivale a una tabla de base de datos
  • Un PF = un miembro por defecto (pero puede tener múltiples miembros)

Logical File (LF)

  • No contiene datos, es una vista sobre uno o más PFs
  • Define un orden (índice/clave) o una selección de campos/registros
  • Equivale a una vista SQL + índice
  • Puede hacer JOIN de múltiples PFs

Miembros (Members)

Un archivo físico puede contener múltiples miembros. Cada miembro tiene el mismo formato de registro pero datos distintos. Esto se usa mucho para source files (ver siguiente sección) y para separar datos por período (ej: un miembro por mes).

Nomenclatura DDS vs SQL

Terminología DDS (tradicional)

Physical File (PF)Contiene datos
Logical File (LF)Vista/índice
Record formatEstructura de registro
FieldCampo del registro
MemberSubdivisión de datos

Terminología SQL (moderna)

TABLE= Physical File
VIEW / INDEX= Logical File
Row= Record
Column= Field
Partition≈ Member
CL — Archivos
CRTPF FILE(MILIB/CLIENTES) SRCFILE(MILIB/QDDSSRC)   Crear PF desde DDS
CRTLF FILE(MILIB/CLIL1) SRCFILE(MILIB/QDDSSRC)      Crear LF desde DDS
DSPFD FILE(MILIB/CLIENTES)                            Descripción del archivo
DSPFFD FILE(MILIB/CLIENTES)                           Descripción de campos
RUNQRY *N MILIB/CLIENTES                              Consulta rápida de datos
CPYF FROMFILE(MILIB/CLIENTES) TOFILE(MILIB/CLIBACK)  Copiar archivo

Source Physical Files

El código fuente en IBM i no se guarda en archivos de texto plano como en x86. Se almacena en Source Physical Files (SPF) — archivos físicos especiales donde cada miembro es un "archivo fuente" (un programa, una DDS, etc.).

MILIBtu biblioteca de desarrollo
QRPGSRCSource PF para fuentes RPG
MIPROGmiembro = código fuente RPG
OTROPROGotro miembro RPG
QCLSRCSource PF para fuentes CL
MISCRIPTmiembro = código fuente CL
QDDSSRCSource PF para DDS (PF/LF/DSPF)
CLIENTESmiembro = DDS del archivo CLIENTES
CLIL1miembro = DDS del logical file

Nombres convencionales de Source Physical Files:

QRPGSRC

Fuentes RPG IV (ILE RPG)

QRPGLESRC

Fuentes RPG IV (alternativo)

QCLSRC

Fuentes CL (Control Language)

QDDSSRC

Fuentes DDS (PF, LF, DSPF, PRTF)

QCBLLESRC

Fuentes COBOL ILE

QCSRC

Fuentes C/C++

QSQLSRC

Fuentes SQL

QCMDSRC

Fuentes de definición de comandos

QTXTSRC

Texto y documentación

CL — Source Physical Files
CRTSRCPF FILE(MILIB/QRPGSRC) RCDLEN(112)    Crear SPF para RPG
WRKMBRPDM FILE(MILIB/QRPGSRC)               Editar fuentes con PDM/SEU
STRSEU SRCFILE(MILIB/QRPGSRC) SRCMBR(MIPROG)  Editar un miembro específico
ADDPFM FILE(MILIB/QRPGSRC) MBR(NUEVO) SRCTYPE(RPGLE)  Agregar miembro
Desarrollo moderno: Hoy se puede usar VS Code + Code for IBM i para editar fuentes directamente en el IFS o en source physical files, con syntax highlighting, autocompletar y control de versiones Git. No es necesario usar SEU.

IFS — Integrated File System

Además de las bibliotecas tradicionales, IBM i tiene un sistema de archivos jerárquico tipo Unix/Windows. El IFS unifica varios sistemas de archivos bajo una única raíz /.

/raíz
home/
FERNANDO/
tmp/
QSYS.LIB/Bibliotecas tradicionales como archivos
QGPL.LIB/
MIAPP.LIB/
QOpenSys/POSIX (case-sensitive)
usr/bin/
QDLS/Document Library Services

El IFS permite almacenar archivos tipo stream (PDFs, XMLs, JSONs, imágenes) y es donde viven las aplicaciones modernas (Java, Node.js, Python). El directorio /QOpenSyses un entorno POSIX completo donde podés instalar herramientas open source con yum.

Sistemas de archivos dentro del IFS

/

Root file system — case-insensitive, almacenamiento general

/QSYS.LIB

Interfaz al sistema de bibliotecas tradicional. Cada biblioteca es un directorio, cada objeto un archivo.

/QOpenSys

POSIX completo, case-sensitive. Aquí corren bash, Python, Node.js, git. Es el puente al mundo moderno.

/QDLS

Document Library Services (legacy). Carpetas compartidas estilo PC.

/QNTC

Acceso a shares de red Windows (CIFS/SMB). Conecta directo a servidores Windows.

Comandos IFS

CL — Comandos IFS
WRKLNK '/'                     Ver el directorio raíz del IFS
WRKLNK '/home'                 Ver el directorio home
MKDIR DIR('/home/FERNANDO/datos')         Crear directorio
CPYTOSTMF                      Copiar archivo tradicional a stream file
CPYFRMSTMF                     Copiar desde IFS a archivo tradicional
CPY OBJ('/home/a.txt') TOOBJ('/home/b.txt')  Copiar en IFS
RMVLNK OBJLNK('/home/viejo.txt')         Borrar archivo del IFS
QShell / PASE — Comandos Unix
QSH                            Entrar a QShell (shell POSIX)
CALL QP2TERM                   Entrar a PASE (shell AIX/bash)
ls -la /home/FERNANDO          Listar archivos
cp archivo.txt /home/FERNANDO  Copiar archivos
python3 /home/scripts/etl.py   Ejecutar script Python

Bibliotecas vs IFS — ¿Cuándo usar cada uno?

Bibliotecas (QSYS.LIB)

  • Programas compilados (*PGM, *SRVPGM)
  • Archivos de datos nativos (*FILE)
  • Objetos del sistema (*DTAARA, *DTAQ, *MSGQ)
  • Código fuente (Source Physical Files)
  • Todo lo que el sistema necesita 'entender'
  • Nombres hasta 10 caracteres (legacy)
  • Sin anidamiento de directorios

IFS (/, /home, /QOpenSys)

  • Archivos stream (PDF, XML, JSON, CSV, imágenes)
  • Aplicaciones Java, Node.js, Python
  • Scripts y herramientas open source
  • Integración con sistemas externos
  • Control de versiones (Git)
  • Nombres largos, case-sensitive en QOpenSys
  • Estructura jerárquica libre
En la práctica: Los programas RPG/COBOL viven en bibliotecas. Los archivos de datos nativos también. Todo lo demás (web apps, scripts, archivos de intercambio) va al IFS. El desarrollo moderno tiende a poner incluso el código fuente en el IFS para poder usar Git.

Subsistemas

Un subsistema es un entorno de ejecución controlado, similar a un servicio o daemon en Linux. Cada subsistema está definido por un objeto *SBSD(Subsystem Description) que especifica qué tipos de trabajos puede ejecutar, cuántos, con qué prioridad y qué recursos asignarles.

QCTLSubsistema de control (arranca primero, es el 'init' del sistema)
QINTERTrabajos interactivos (sesiones 5250 de usuarios)
QBATCHTrabajos por lotes (batch) — ejecuciones programadas o enviadas
QSPLTrabajos de impresión (spool) — gestiona colas de impresión
QSERVERServidores de archivos/impresión para PCs (NetServer, etc.)
QUSRWRKTrabajos del usuario (servidores HTTP, FTP, SMTP, etc.)
QSYSWRKTrabajos del sistema (monitores, servicios internos)

Comandos de subsistemas

CL — Subsistemas
WRKSBS                         Ver subsistemas activos
WRKSBSJOB SBS(QINTER)         Ver trabajos de un subsistema
STRSBS SBSD(QBATCH)           Arrancar un subsistema
ENDSBS SBS(QBATCH) OPTION(*IMMED)  Detener un subsistema
DSPSBSD SBSD(QINTER)          Ver la descripción/configuración

Trabajos (Jobs)

Todo lo que se ejecuta en IBM i es un job. Un job tiene un nombre único compuesto por tres partes:

123456/FERNANDO/QPADEV0001
Nro. de trabajoUsuarioNombre del trabajo

Tipos de trabajo:

Interactivo

Sesión de usuario conectado por 5250. Responde a teclas y pantallas.

Batch

Trabajo enviado a ejecutarse en segundo plano. No tiene pantalla.

Autostart

Se inicia automáticamente con el subsistema. Ideal para servidores.

Server

Trabajos de servidor (HTTP, FTP, base de datos, SMTP, etc.).

Job Description (*JOBD)

Cada trabajo se crea basándose en un Job Description que define su library list inicial, la cola de salida, la cola de trabajos, prioridad de ejecución y más. Es como un template de configuración para trabajos.

Comandos para gestionar trabajos

CL — Gestión de Jobs
WRKACTJOB                      Ver todos los trabajos activos
WRKACTJOB SBS(QINTER)         Ver solo trabajos interactivos
WRKACTJOB JOB(FERNANDO)       Ver trabajos de un usuario
WRKSBSJOB QBATCH              Ver trabajos del subsistema batch
SBMJOB CMD(CALL MIPROG) JOB(MINOCHE)  Enviar programa a batch
ENDJOB JOB(123456/FERNANDO/MIPROG) OPTION(*IMMED)  Finalizar
HLDJOB                         Pausar un trabajo
RLSJOB                         Reanudar un trabajo pausado
DSPJOB                         Ver detalle del trabajo actual
CHGJOB RUNPTY(20)              Cambiar prioridad de ejecución

Job Queues y Output Queues

Job Queue (*JOBQ)

Cola donde esperan los trabajos batch antes de ejecutarse. El subsistema toma trabajos de la cola según prioridad y límite de trabajos activos. Es como una cola de tareas (task queue) de un sistema de colas moderno (RabbitMQ, SQS).

Output Queue (*OUTQ)

Cola donde se almacenan los spool files (salidas impresas). Cada usuario tiene una output queue por defecto. Los reportes generados van aquí antes de imprimirse o descargarse.

CL — Colas
WRKJOBQ JOBQ(QBATCH)          Ver la cola de trabajos batch
WRKOUTQ OUTQ(QPRINT)          Ver la cola de salida
HLDJOBQ JOBQ(QBATCH)          Pausar la cola (no procesa más trabajos)
RLSJOBQ JOBQ(QBATCH)          Reanudar la cola
CLROUTQ OUTQ(MIOUTQ)          Limpiar una output queue

Spool Files

Cuando un programa genera salida impresa (reportes, listados, etc.), esa salida no va directamente a la impresora. Se almacena como un spool file en una output queue. Desde ahí podés verlo, descargarlo, imprimirlo o borrarlo.

Es el equivalente a un PDF generado por un proceso batch que queda en una carpeta de salida.

CL — Spool Files
WRKSPLF                        Ver tus spool files
WRKSPLF SELECT(*CURRENT)      Solo los del trabajo actual
DSPSPLF FILE(MIREPORTE)       Ver contenido de un spool file
CPYSPLF FILE(MIREPORTE) TOFILE(MILIB/SALIDA)  Copiar a archivo
DLTSPLF FILE(MIREPORTE)       Borrar un spool file
SNDNETSPLF                    Enviar spool file a otro sistema
Tip: Podés convertir spool files a PDF usando el comando CPYSPLF ... TOSTMF para generar un archivo en el IFS, o usar herramientas de IBM ACS para descargarlos directamente como PDF.

Message Queues

Las colas de mensajes son el sistema de comunicación entre trabajos y entre el sistema y los usuarios. Cada usuario tiene una message queue personal, y hay colas especiales del sistema.

QSYSOPR

Cola del operador del sistema. Aquí llegan mensajes críticos y de atención.

User MSGQ

Cada perfil de usuario tiene su propia cola. Mensajes de break, notificaciones.

Job MSGQ

Cada trabajo tiene su cola interna. Los mensajes de error van aquí (job log).

*DTAQ

Data Queues — colas programáticas para comunicación entre programas. Más rápidas que message queues.

CL — Message Queues
DSPMSG MSGQ(QSYSOPR)          Ver mensajes del operador del sistema
DSPMSG MSGQ(FERNANDO)          Ver tus mensajes personales
SNDMSG MSG('Proceso completado') TOUSR(FERNANDO)  Enviar mensaje
SNDBRKMSG MSG('Urgente') TOUSR(*ALLACT)  Mensaje a todos los activos
CLRMSGQ MSGQ(FERNANDO)        Limpiar tu cola de mensajes

Data Areas (*DTAARA)

Un Data Area es un objeto que almacena un valor persistente — puede ser un string, un número decimal o lógico. Se usa comúnmente para:

  • Parámetros de configuración de la aplicación (rutas, flags, versiones)
  • Contadores persistentes (número de factura, secuencia)
  • Semáforos simples (indicar si un proceso está corriendo)
  • Comunicación de estado entre programas

Existe un data area especial por biblioteca: LDA (Local Data Area), que es privado de cada trabajo y se usa para pasar información entre programas dentro del mismo job.

CL — Data Areas
CRTDTAARA DTAARA(MILIB/CONFIG) TYPE(*CHAR) LEN(100) VALUE('PROD')
DSPDTAARA DTAARA(MILIB/CONFIG)             Ver el valor actual
CHGDTAARA DTAARA(MILIB/CONFIG) VALUE('DEV')  Cambiar el valor
RTVDTAARA DTAARA(MILIB/CONFIG) RTNVAR(&VAR)  Leer en CL program
DLTDTAARA DTAARA(MILIB/CONFIG)             Eliminar data area
Comparación x86: Un Data Area es como una variable de entorno persistente, o como un registro en una tabla de configuración. La diferencia es que al ser un objeto nativo del sistema, tiene locking automático y es atómico para lecturas/escrituras concurrentes.

Job Logs y diagnóstico

Cada trabajo mantiene un job log — un registro cronológico de todos los mensajes generados durante su ejecución. Es el equivalente al log de una aplicación, pero gestionado por el sistema operativo.

El job log incluye:

  • Mensajes informativos (inicio/fin de programas)
  • Mensajes de diagnóstico y escape (errores)
  • Comandos ejecutados
  • Mensajes de notificación
  • Información de rendimiento (opcional)

Comandos de diagnóstico

CL — Diagnóstico
DSPJOBLOG                      Ver el job log del trabajo actual
DSPJOBLOG JOB(123456/FERNANDO/MIPROG)    Job log de otro trabajo
WRKJOB                         Opciones del trabajo actual
DSPJOB                         Atributos del trabajo actual
WRKSYSSTS                      Estado del sistema (CPU, memoria, disco)
WRKSYSACT                      Actividad del sistema en tiempo real
WRKDSKSTS                      Estado de los discos (ASPs)
DSPMSG MSGQ(*SYSOPR)          Mensajes del operador (errores del sistema)

Niveles de logging

El nivel de detalle del job log se controla con el parámetro LOG del job o job description. El formato es LOG(nivel severidad texto):

LOG(0 0 *NOLIST)

Sin job log — solo errores fatales

LOG(1 0 *NOLIST)

Mínimo — solo mensajes de escape

LOG(2 20 *SECLVL)

Normal — errores y diagnósticos

LOG(4 0 *SECLVL)

Máximo — todo, incluyendo comandos ejecutados

Tip práctico: Si un programa falla en batch, lo primero es ir a WRKSBSJOB QBATCH, buscar el trabajo que falló, y con opción 5 ver su job log. El último mensaje de tipo *ESCAPE te dice qué pasó. También podés usar DSPJOBLOG vía SQL desde la vista QSYS2.JOBLOG_INFO.