PASE y Open Source

PASE for i como capa de compatibilidad AIX, gestion de paquetes con yum, Node.js, Python, PHP, Git y herramientas open source ejecutandose nativamente en IBM i. Integracion entre el mundo open source y la plataforma nativa.

Que es PASE for i

PASE for i (Portable Application Solutions Environment) es una capa de runtime integrada en IBM i que permite ejecutar binarios compilados para AIX (IBM Unix) directamente en el sistema. PASE proporciona un entorno POSIX completo con su propio sistema de archivos, shell y librerias compartidas, todo corriendo sobre el mismo kernel de IBM i.

Compatibilidad AIX

Ejecuta binarios PowerPC AIX sin recompilacion. Mismas librerias y APIs POSIX.

IFS integrado

Comparte el sistema de archivos IFS con el entorno nativo IBM i. Acceso transparente.

Shell completo

Bash, sh, ksh disponibles. Pipes, redirects, scripts funcionan igual que en Unix.

Perfiles IBM i

PASE usa los mismos perfiles de usuario y permisos que el entorno nativo.

Networking compartido

PASE comparte la misma pila TCP/IP. Las apps escuchan en los mismos puertos.

Open source

Node.js, Python, PHP, Ruby, Git, gcc y cientos de paquetes disponibles.

Arquitectura de PASE for i
+--------------------------------------------------+
|              Aplicaciones IBM i                   |
|  RPG  |  COBOL  |  CL  |  SQL  |  Java           |
+--------------------------------------------------+
|    MI (Machine Interface) - Kernel IBM i          |
+--------------------------------------------------+
|              PASE for i Runtime                   |
|  +--------------------------------------------+  |
|  |  Binarios AIX / PowerPC                    |  |
|  |  Node.js | Python | PHP | Git | gcc        |  |
|  |  Bash | coreutils | openssl | curl         |  |
|  +--------------------------------------------+  |
|  |  Librerias AIX: libc, libpthread, libdl    |  |
|  +--------------------------------------------+  |
+--------------------------------------------------+
|    IFS (Integrated File System) compartido        |
|    /home  /QOpenSys  /QSYS.LIB  /tmp             |
+--------------------------------------------------+
Shell -- Primeros pasos en PASE
// Acceder a PASE desde 5250 con CALL QP2TERM
CALL QP2TERM

// O desde SSH (recomendado):
ssh miusuario@miibmi

// Verificar que estamos en PASE
$ uname -a
AIX miibmi 1 7 00F6B9F74C00

// Verificar version de PASE
$ /QOpenSys/usr/bin/oslevel
7.2.0.0

// Ver el PATH por defecto
$ echo $PATH
/QOpenSys/pkgs/bin:/QOpenSys/usr/bin:/usr/bin

// Listar archivos en IFS (acceso completo)
$ ls /QSYS.LIB/MILIB.LIB/
CLIENTES.FILE  FACTURAS.FILE  MIPGM.PGM

Package management con yum

IBM distribuye paquetes open source para IBM i a traves de un repositorio RPM gestionado con yum (el mismo gestor de paquetes de Red Hat/CentOS). La instalacion inicial se realiza desde ACS (Access Client Solutions)y luego se gestionan los paquetes desde la linea de comandos.

Instalacion inicial (una sola vez)

  • 1. Abrir ACS (Access Client Solutions)
  • 2. Ir a Tools > Open Source Package Management
  • 3. Conectar al IBM i destino
  • 4. Instalar el bootstrap (yum + dependencias base)
  • 5. Una vez instalado, usar SSH para gestionar paquetes

Estructura de directorios

  • /QOpenSys/pkgs/ -- Raiz de paquetes open source
  • /QOpenSys/pkgs/bin/ -- Binarios (node, python3, git)
  • /QOpenSys/pkgs/lib/ -- Librerias compartidas
  • /QOpenSys/pkgs/etc/ -- Configuracion
  • /QOpenSys/pkgs/share/ -- Datos y documentacion
Shell -- Comandos yum esenciales
// Actualizar el catalogo de paquetes
$ yum update

// Buscar paquetes disponibles
$ yum search nodejs
$ yum search python3

// Ver informacion de un paquete
$ yum info nodejs18

// Instalar paquetes
$ yum install nodejs18
$ yum install python39
$ yum install git
$ yum install bash
$ yum install curl
$ yum install openssh

// Instalar multiples paquetes de una vez
$ yum install nodejs18 python39 git bash-completion

// Ver paquetes instalados
$ yum list installed

// Eliminar un paquete
$ yum remove nodejs14

// Ver paquetes que tienen actualizacion disponible
$ yum check-update

// Actualizar un paquete especifico
$ yum upgrade nodejs18
Importante: Siempre ejecutar yum update antes de instalar paquetes nuevos para asegurar que el catalogo esta actualizado. Los paquetes se instalan en /QOpenSys/pkgs/ y no interfieren con el sistema operativo nativo de IBM i.

Node.js en IBM i

Node.js corre nativamente en IBM i gracias a PASE. Es una de las opciones mas populares para crear aplicaciones web modernas que interactuan con datos y programas IBM i. Soporta npm completo, Express, frameworks modernos y acceso a Db2 via ODBC.

Shell -- Instalar y verificar Node.js
// Instalar Node.js 18 LTS
$ yum install nodejs18

// Verificar instalacion
$ node --version
v18.19.0

$ npm --version
9.8.1

// Crear directorio de proyecto
$ mkdir -p /home/MIUSER/proyectos/mi-api
$ cd /home/MIUSER/proyectos/mi-api

// Inicializar proyecto Node.js
$ npm init -y

// Instalar dependencias comunes
$ npm install express
$ npm install odbc          # Driver ODBC para Db2
$ npm install itoolkit      # Llamar programas RPG
$ npm install dotenv        # Variables de entorno
app.js -- API Express sobre IBM i con Db2
const express = require('express');
const odbc = require('odbc');
const app = express();

app.use(express.json());

// Conexion ODBC a Db2 for i
const DSN = 'DSN=*LOCAL;DBQ=MILIB;';

// GET /api/clientes - Listar clientes
app.get('/api/clientes', async (req, res) => {
  try {
    const conn = await odbc.connect(DSN);
    const result = await conn.query(
      'SELECT CLI_ID as id, CLI_NOM as nombre, ' +
      'CLI_MAIL as email, CLI_SALDO as saldo ' +
      'FROM MILIB.CLIENTES ' +
      'WHERE CLI_ACTIV = ? ORDER BY CLI_NOM',
      ['A']
    );
    await conn.close();
    res.json({ data: result, count: result.length });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// GET /api/clientes/:id - Obtener un cliente
app.get('/api/clientes/:id', async (req, res) => {
  try {
    const conn = await odbc.connect(DSN);
    const result = await conn.query(
      'SELECT * FROM MILIB.CLIENTES WHERE CLI_ID = ?',
      [req.params.id]
    );
    await conn.close();

    if (result.length === 0) {
      return res.status(404).json({ error: 'No encontrado' });
    }
    res.json(result[0]);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// POST /api/clientes - Crear cliente
app.post('/api/clientes', async (req, res) => {
  const { nombre, email } = req.body;
  try {
    const conn = await odbc.connect(DSN);
    await conn.query(
      'INSERT INTO MILIB.CLIENTES ' +
      '(CLI_NOM, CLI_MAIL, CLI_SALDO, CLI_ACTIV) ' +
      'VALUES (?, ?, 0, ?)',
      [nombre, email, 'A']
    );
    await conn.close();
    res.status(201).json({ message: 'Cliente creado' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log('API corriendo en puerto ' + PORT);
});
Shell -- Ejecutar la app Node.js
// Ejecutar en primer plano (desarrollo)
$ cd /home/MIUSER/proyectos/mi-api
$ node app.js
API corriendo en puerto 3000

// Ejecutar en background con nohup
$ nohup node app.js > /home/MIUSER/logs/api.log 2>&1 &

// Usar PM2 para gestion de procesos en produccion
$ npm install -g pm2
$ pm2 start app.js --name "mi-api"
$ pm2 list
$ pm2 logs mi-api
$ pm2 restart mi-api

// Probar el endpoint
$ curl http://localhost:3000/api/clientes
{"data":[...],"count":42}

Python en IBM i

Python es ideal para scripting, automatizacion, ETL, analisis de datos y aplicaciones web en IBM i. Incluye soporte completo para pip, virtualenvs y acceso a Db2 mediante el paquete ibm_db o via ODBC.

Shell -- Instalar y configurar Python
// Instalar Python 3.9
$ yum install python39 python39-pip python39-devel

// Verificar instalacion
$ python3 --version
Python 3.9.18

$ pip3 --version
pip 23.2.1

// Crear virtual environment (buena practica)
$ python3 -m venv /home/MIUSER/venvs/miproyecto
$ source /home/MIUSER/venvs/miproyecto/bin/activate

// Instalar dependencias
(miproyecto)$ pip install ibm_db       # Driver nativo Db2
(miproyecto)$ pip install itoolkit     # Llamar programas RPG
(miproyecto)$ pip install flask        # Framework web
(miproyecto)$ pip install pandas       # Analisis de datos
(miproyecto)$ pip install openpyxl     # Manejo de Excel
consulta_db2.py -- Acceso a Db2 desde Python
import ibm_db_dbi as db2

# Conexion local a Db2 for i
conn = db2.connect()

# Consultar clientes activos
cursor = conn.cursor()
cursor.execute("""
    SELECT CLI_ID, CLI_NOM, CLI_MAIL, CLI_SALDO
      FROM MILIB.CLIENTES
     WHERE CLI_ACTIV = 'A'
     ORDER BY CLI_NOM
     FETCH FIRST 100 ROWS ONLY
""")

# Iterar resultados
for row in cursor:
    print(f"ID: {row[0]}, Nombre: {row[1]}, "
          f"Saldo: {row[3]:,.2f}")

# Insert con parametros
cursor.execute("""
    INSERT INTO MILIB.CLIENTES
      (CLI_NOM, CLI_MAIL, CLI_SALDO, CLI_ACTIV)
    VALUES (?, ?, ?, ?)
""", ('Nuevo Cliente', 'nuevo@email.com', 0, 'A'))

conn.commit()
cursor.close()
conn.close()
automatizar.py -- Script de automatizacion
#!/QOpenSys/pkgs/bin/python3
"""
Script de automatizacion: exportar clientes a CSV
Puede ejecutarse desde CL con: QSH CMD('python3 /path/automatizar.py')
"""
import ibm_db_dbi as db2
import csv
from datetime import datetime

conn = db2.connect()
cursor = conn.cursor()

cursor.execute("""
    SELECT CLI_ID, CLI_NOM, CLI_MAIL, CLI_SALDO,
           CLI_ACTIV, CLI_FALTA
      FROM MILIB.CLIENTES
     ORDER BY CLI_NOM
""")

# Generar archivo CSV en IFS
fecha = datetime.now().strftime('%Y%m%d')
archivo = f'/home/MIUSER/exports/clientes_{fecha}.csv'

with open(archivo, 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['ID', 'Nombre', 'Email',
                     'Saldo', 'Activo', 'FechaAlta'])
    for row in cursor:
        writer.writerow(row)

print(f"Exportados {cursor.rowcount} registros a {archivo}")

cursor.close()
conn.close()
Automatizacion desde CL: Se pueden ejecutar scripts Python desde programas CL usando el comando QSH CMD('python3 /ruta/script.py') o programando su ejecucion con el planificador de jobs de IBM i (ADDJOBSCDE).

PHP en IBM i

PHP tiene una larga historia en IBM i y sigue siendo una opcion solida para aplicaciones web, especialmente para modernizar interfaces 5250 a web. El driver nativo ibm_db2 permite acceso directo a Db2 for i.

Shell -- Instalar PHP
// Instalar PHP 8.1 con extensiones comunes
$ yum install php81 php81-cli php81-fpm
$ yum install php81-ibm_db2      # Driver Db2
$ yum install php81-odbc         # ODBC alternativo
$ yum install php81-json php81-xml php81-mbstring
$ yum install php81-curl php81-zip

// Verificar instalacion
$ php --version
PHP 8.1.25

// Verificar extensiones
$ php -m | grep -i db2
ibm_db2

// Instalar Composer (gestor de dependencias PHP)
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php --install-dir=/QOpenSys/pkgs/bin --filename=composer
clientes.php -- Aplicacion web PHP con Db2
<?php
// clientes.php - Listado de clientes desde Db2 for i
$conn = db2_connect('*LOCAL', '', '');

if (!$conn) {
    die('Error de conexion: ' . db2_conn_errormsg());
}

// Consultar clientes
$sql = "SELECT CLI_ID, CLI_NOM, CLI_MAIL, CLI_SALDO
          FROM MILIB.CLIENTES
         WHERE CLI_ACTIV = 'A'
         ORDER BY CLI_NOM";
$stmt = db2_exec($conn, $sql);

// Generar respuesta JSON (para APIs)
header('Content-Type: application/json');
$clientes = [];

while ($row = db2_fetch_assoc($stmt)) {
    $clientes[] = [
        'id'     => (int)$row['CLI_ID'],
        'nombre' => trim($row['CLI_NOM']),
        'email'  => trim($row['CLI_MAIL']),
        'saldo'  => (float)$row['CLI_SALDO'],
    ];
}

echo json_encode([
    'data'  => $clientes,
    'count' => count($clientes)
]);

db2_close($conn);

Git en IBM i

Git corre nativamente en IBM i via PASE y es la base del flujo de trabajo moderno para versionado de fuentes. Tanto el codigo fuente almacenado en IFS como el extraido de source physical files puede gestionarse con Git.

Shell -- Instalar y configurar Git
// Instalar Git
$ yum install git

// Verificar
$ git --version
git version 2.39.3

// Configuracion inicial
$ git config --global user.name "Fernando Secchi"
$ git config --global user.email "fernando@empresa.com"
$ git config --global core.autocrlf input
$ git config --global init.defaultBranch main

// Configurar SSH para GitHub/GitLab
$ ssh-keygen -t ed25519 -C "fernando@empresa.com"
$ cat ~/.ssh/id_ed25519.pub
// Copiar la clave publica y agregarla en GitHub/GitLab
Shell -- Flujo Git con fuentes IBM i
// Crear repositorio para fuentes RPG
$ mkdir -p /home/MIUSER/repos/mi-proyecto
$ cd /home/MIUSER/repos/mi-proyecto
$ git init

// Estructura de directorios recomendada
$ mkdir -p qrpglesrc qclsrc qddssrc qcmdsrc qsqlsrc

// Copiar fuentes desde source physical files
$ system "CPYTOSTMF FROMMBR('/QSYS.LIB/MILIB.LIB/QRPGLESRC.FILE/GESTCLI.MBR')   TOSTMF('/home/MIUSER/repos/mi-proyecto/qrpglesrc/gestcli.rpgle')   STMFOPT(*REPLACE) STMFCCSID(1208)"

// Agregar archivos y hacer primer commit
$ git add .
$ git commit -m "feat: migracion inicial de fuentes RPG"

// Conectar con repositorio remoto
$ git remote add origin git@github.com:empresa/mi-proyecto.git
$ git push -u origin main

// Flujo diario de trabajo
$ git pull origin main           # Traer cambios
$ git checkout -b feature/nueva  # Crear branch
// ... editar archivos ...
$ git add qrpglesrc/gestcli.rpgle
$ git commit -m "feat: agregar validacion de email"
$ git push origin feature/nueva  # Subir cambios

Source Physical Files (tradicional)

  • Fuentes en QSYS: QRPGLESRC, QCLSRC
  • Sin historial de cambios
  • PDM/SEU como unico editor
  • Backup manual o via SAVLIB
  • Colaboracion por bloqueo de miembros

Git + IFS (moderno)

  • Fuentes en IFS: /home/user/repos/
  • Historial completo de cada cambio
  • VS Code + Code for i como editor
  • Backup automatico en GitHub/GitLab
  • Colaboracion via branches y pull requests

iToolkit: RPG desde lenguajes open source

iToolkit es una libreria disponible para Node.js, Python y PHP que permite llamar programas RPG, ejecutar comandos CL y acceder a data queues directamente desde codigo open source. Es el puente entre el mundo PASE y el entorno nativo IBM i.

Node.js -- Llamar programa RPG con iToolkit
const { Connection, ProgramCall } = require('itoolkit');
const { parseString } = require('itoolkit/lib/utils');

// Conexion al sistema local
const conn = new Connection({
  transport: '*local',
  transportOptions: { database: '*LOCAL' }
});

// Llamar al programa GESTCLI con parametros
const pgm = new ProgramCall('GESTCLI', { lib: 'MILIB' });

pgm.addParam({ name: 'accion',    type: '10A',  value: 'CONS' });
pgm.addParam({ name: 'id',        type: '7P0',  value: '1001' });
pgm.addParam({ name: 'nombre',    type: '100A', value: '' });
pgm.addParam({ name: 'email',     type: '200A', value: '' });
pgm.addParam({ name: 'resultado', type: '1A',   value: '' });

conn.add(pgm);
conn.run((error, xmlOutput) => {
  if (error) {
    console.error('Error:', error);
    return;
  }

  const results = parseString(xmlOutput);
  console.log('Nombre:', results[2].value.trim());
  console.log('Email:', results[3].value.trim());
  console.log('Resultado:', results[4].value);
});
Python -- Llamar programa RPG con iToolkit
from itoolkit import iToolKit, iPgm, iData, iDS
from itoolkit.transport import DatabaseTransport

# Conexion local
import ibm_db_dbi as db2
conn = db2.connect()
transport = DatabaseTransport(conn)

tk = iToolKit()

# Llamar programa GESTCLI
tk.add(iPgm('gestcli', 'GESTCLI', {'lib': 'MILIB'})
    .addParm(iData('accion', '10A', 'CONS'))
    .addParm(iData('id', '7P0', '1001'))
    .addParm(iData('nombre', '100A', ''))
    .addParm(iData('email', '200A', ''))
    .addParm(iData('resultado', '1A', ''))
)

tk.call(transport)
result = tk.dict_out('gestcli')

print(f"Nombre: {result['nombre'].strip()}")
print(f"Email: {result['email'].strip()}")
print(f"Resultado: {result['resultado']}")

conn.close()
PHP -- Llamar programa RPG con iToolkit
<?php
require_once 'ToolkitService.php';

// Conexion al toolkit
$conn = ToolkitService::getInstance('*LOCAL', '', '');

// Parametros del programa
$params = [
    $conn->AddParameterChar('in',  10, 'accion',    'ACCION', 'CONS'),
    $conn->AddParameterPackDec('in', 7, 0, 'id',    'ID', '1001'),
    $conn->AddParameterChar('out', 100, 'nombre',   'NOMBRE', ''),
    $conn->AddParameterChar('out', 200, 'email',    'EMAIL', ''),
    $conn->AddParameterChar('out', 1,   'resultado','RESULTADO', ''),
];

// Llamar al programa RPG
$result = $conn->PgmCall('GESTCLI', 'MILIB', $params);

if ($result !== false) {
    echo "Nombre: " . trim($result['io_param']['nombre']) . "
";
    echo "Email: " . trim($result['io_param']['email']) . "
";
    echo "Resultado: " . $result['io_param']['resultado'] . "
";
}
?>
Caso de uso ideal: iToolkit es perfecto cuando necesitas una app web moderna (Node.js/Python/PHP) que reutilice logica de negocio existente en programas RPG sin modificarlos. La app open source maneja la UI y orquestacion; RPG maneja las reglas de negocio y acceso a datos.

SSH y acceso remoto

SSH es el metodo recomendado para acceder a PASE de forma remota. Reemplaza a CALL QP2TERM (desde 5250) y proporciona una experiencia de terminal completa con soporte para claves publicas, tuneles y SCP para transferencia de archivos.

CL -- Iniciar servidor SSH en IBM i
// Iniciar el servidor SSH (como administrador)
STRTCPSVR SERVER(*SSHD)

// Verificar que esta activo
WRKACTJOB SBS(QUSRWRK) JOB(SSHD)

// Configurar inicio automatico con IPL
CHGTCPSVR SVRSPCVAL(*SSHD) AUTOSTART(*YES)

// Verificar puerto (default 22)
NETSTAT *CNN
// Buscar Local Port 22
Shell -- Configuracion SSH del cliente
# En tu maquina local: ~/.ssh/config
Host miibmi
    HostName 192.168.1.100
    User MIUSER
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

# Conectar con un simple:
$ ssh miibmi

# Copiar archivos con SCP
$ scp archivo.rpgle miibmi:/home/MIUSER/repos/src/
$ scp miibmi:/home/MIUSER/exports/datos.csv ./local/

# Copiar directorios completos
$ scp -r ./mi-proyecto/ miibmi:/home/MIUSER/repos/

# Ejecutar comando remoto sin sesion interactiva
$ ssh miibmi "system 'DSPLIB MILIB'"
$ ssh miibmi "python3 /home/MIUSER/scripts/backup.py"

Integracion PASE con nativo

Una de las mayores fortalezas de PASE es la integracion transparente con el entorno nativo de IBM i. Desde PASE se pueden ejecutar comandos CL, acceder a objetos QSYS, leer/escribir data queues y ejecutar sentencias SQL directamente.

Shell -- Ejecutar comandos CL desde PASE
// El comando 'system' permite ejecutar CL desde PASE
$ system "DSPLIB MILIB"
$ system "WRKOBJPDM LIB(MILIB)"

// Compilar un programa RPG desde PASE
$ system "CRTBNDRPG PGM(MILIB/GESTCLI)   SRCSTMF('/home/MIUSER/repos/qrpglesrc/gestcli.rpgle')   DBGVIEW(*SOURCE)"

// Ejecutar un programa nativo desde PASE
$ system "CALL MILIB/GESTCLI PARM('CONS' X'001001F' ' ' ' ' ' ')"

// Enviar mensaje a QSYSOPR
$ system "SNDMSG MSG('Deploy completado') TOUSR(*SYSOPR)"

// Usar db2util para SQL desde shell
$ /QOpenSys/pkgs/bin/db2util "SELECT COUNT(*) FROM MILIB.CLIENTES"

// Usar variables de entorno IBM i
$ system "ADDENVVAR ENVVAR('MI_CONFIG') VALUE('/home/app/config')"
$ echo $MI_CONFIG
Desde PASEMecanismoEjemplo
Ejecutar CLsystem commandsystem 'DSPLIB MILIB'
Acceder Db2ODBC / ibm_dbSELECT * FROM MILIB.TABLA
Llamar RPGiToolkit / IWSiPgm('MIPGM', 'MILIB')
Leer IFS/QSYSFilesystemls /QSYS.LIB/MILIB.LIB/
Data QueuesiToolkitiDataQueue('MIDTAQ', 'MILIB')
Data AreasiToolkit / CLsystem 'DSPDTAARA MIDTAARA'

Buenas practicas

Organizacion de proyectos

  • Usar directorios home por usuario: /home/MIUSER/
  • Separar proyectos en /home/MIUSER/repos/
  • Configurar PATH en .bash_profile
  • Usar virtual environments para Python
  • package.json para cada proyecto Node.js

Seguridad

  • Usar SSH keys en lugar de passwords
  • Configurar .bash_profile con permisos 600
  • No ejecutar apps como QSECOFR
  • Separar perfiles para desarrollo y produccion
  • Usar HTTPS para todas las apps web

Rendimiento

  • PM2 para Node.js en produccion
  • Connection pooling para Db2
  • Monitorear uso de memoria en PASE
  • Usar SBMJOB para tareas largas
  • Logs rotativos para apps en background

Mantenimiento

  • yum update periodico para parches de seguridad
  • Documentar versiones de runtime en uso
  • Backup de /QOpenSys y /home en BRMS
  • Monitorear espacio en IFS con df -h
  • Limpiar /tmp periodicamente
.bash_profile -- Configuracion recomendada
# /home/MIUSER/.bash_profile
# Configuracion recomendada para desarrollo en IBM i

# PATH con paquetes open source primero
export PATH="/QOpenSys/pkgs/bin:$PATH"

# Editor por defecto
export EDITOR=vim

# Locale UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# Node.js
export NODE_ENV=development

# Python virtual env por defecto
alias activate='source /home/MIUSER/venvs/miproyecto/bin/activate'

# Alias utiles para IBM i
alias cls='system "CLRLIB QTEMP"'
alias dsplib='system "DSPLIB"'
alias wrkobjpdm='system "WRKOBJPDM"'
alias db2='db2util'

# Git prompt (muestra branch actual)
parse_git_branch() {
  git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\u@\h:\w\$(parse_git_branch)\$ "
Estrategia recomendada: Usar PASE y open source como complemento, no como reemplazo. La logica de negocio en RPG sigue siendo el corazon del sistema. Node.js/Python/PHP son ideales para la capa de presentacion, integracion y automatizacion, conectandose a RPG via iToolkit o APIs REST.