Comment retrouver les commandes modifiées d’une partition IBM i

IBM fournit des centaines de commandes CL (Control Language) avec son Operating System IBM i. Les paramètres par défaut de ces commandes peuvent être modifiés par un administrateur afin de personnaliser l’environnement et de l’adapter aux besoins d’exploitation de l’entreprise.

En 7.4, suivant les options installées, il y a environ 2000 commandes CL disponibles pour gérer les différentes fonctions de l’Operating System IBM i.

Lors d’un changement de version, IBM remplace toutes les commandes par celles de la nouvelle version et repositionne les paramètres par défaut. Ainsi, toutes les modifications qui ont pu être apportées sur un système sont supprimées.

Il faut donc, avant tout changement de version, recenser les commandes concernées, pour ensuite pouvoir repositionner les bons paramètres.

Alors, comment repérer les commandes IBM qui ont été modifiées ?

Jusqu’en V5R4, une commande CL et une requête SQL suffisaient pour repérer toutes les commandes modifiées.

On pouvait donc utiliser la commande DSPOBJD qui stockait la liste de toutes les commandes de QSYS dans un fichier, puis il suffisait d’exécuter une requête avec pour critère de sélection le paramètre ODAPAR égal à CHGDFT. Cela donnait la liste des commandes qui avaient été modifiées.

DSPOBJD OBJ(QSYS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB)
SELECT * FROM QTEMP/BIB WHERE ODAPAR = 'CHGDFT'

Jusqu’en V5R4, les commandes IBM étaient toutes stockées dans la bibliothèque QSYS. Ce n’est plus le cas depuis la V6R1.

Prenons un exemple pour illustrer le problème lié aux versions depuis la V6R1. Nous allons modifier un paramètre par défaut d’une commande IBM (ex avec la commande CRTBNDRPG).

Modifions le paramètre DBGVIEW en le passant à *ALL.

CHGCMDDFT CMD(CRTBNDRPG) NEWDFT('DBGVIEW(*ALL)')

Lorsque l’on appelle la commande, on peut constater que le paramètre DBGVIEW a bien été modifié, cela signifie que cette commande n’a plus les valeurs par défaut proposées par IBM.

Il suffit ensuite d’utiliser, dans ACS, la commande CL et la requête SQL que nous avons vus précédemment, afin de valider que cette commande soit bien considérée comme modifiée.

CL:  DSPOBJD OBJ(QSYS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB);
SELECT * FROM QTEMP.BIB WHERE ODAPAR = 'CHGDFT';

Or, le résultat est … nul. Avec cette méthode, nous ne trouvons aucune commande modifiée alors pourtant qu’il devrait y en avoir au moins une.

Pour quelle raison la commande modifiée n’apparait pas dans la liste ?

La raison est liée aux commandes proxy, apparues en 6.1. Les commandes proxy sont des pseudo-commandes pointant sur des vraies commandes. Cela implique donc que les commandes CL IBM ne sont donc plus forcément dans QSYS.

Si l’on regarde la liste des commandes de QSYS, plusieurs centaines d’entre elles sont de type proxy (Attribut PRX). C’est le cas de la commande utilisée dans notre exemple (CRTBNDRPG).


Faisons une recherche de cette commande sur l’intégralité du système :

WRKOBJ OBJ(*ALL/CRTBNDRPG) OBJTYPE(*CMD)

Résultat, nous trouvons la commande dans les bibliothèques QSYSV7R2M0 et QSYSV7R3M0, mais cela correspond aux fonctions pour les compilations dans les versions précédentes, et nous trouvons bien la commande dans QSYS en type proxy (PRX), et surtout la commande réelle se trouve dans QDEVTOOLS, option *BASE du produit 5770-WDS (IBM Rational Development Studio for i).


La principale différence entre une commande proxy et une commande CL consiste dans le fait que la proxy n’est qu’un pointeur vers une commande CL. La commande proxy seule, ne peut exécuter aucune action. Dans une commande proxy, les seuls paramètres à renseigner, sont le nom et la bibliothèque de la vraie commande CL que l’on souhaite exécuter.

Exemple avec la commande proxy QSYS/CRTBNDRPG qui pointe réellement sur QDEVTOOLS/CRTBNDRPG.

DSPCMD CMD(QSYS/CRTBNDRPG)

Les différents paramètres et les modes d’exécution sont donc stockés dans la commande CL (ex : QDEVTOOLS/CRTBNDRPG).

DSPCMD CMD(QDEVTOOLS/CRTBNDRPG)

Désormais que nous savons que les commandes CL IBM ne sont plus systématiquement dans la bibliothèque QSYS, il faut donc élargir le champ de recherche à la liste des bibliothèques IBM dans lesquelles se trouvent les différentes commandes.

Ci-dessous, les instructions qui peuvent être utilisées pour la détermination des commandes modifiées. Cette liste contient les bibliothèques dans lesquelles se trouvent les commandes CL IBM pour la quasi-intégralité des options installées sur une partition IBM i. Toutefois, libre à chacun d’en ajouter une qui ne serait pas présente dans cette liste et qui correspondrait à un produit IBM “exotique”.

CL: DSPOBJD OBJ(QSYS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *REPLACE);
CL: DSPOBJD OBJ(QBRM/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QDEVTOOLS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QHTTPSVR/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QIWA2/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QIWS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QJAVA/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QMGTOOLS/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QPDA/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QPFR/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QQRYLIB/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QSHELL/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QSQL/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QSR/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
CL: DSPOBJD OBJ(QTCP/*ALL) OBJTYPE(*CMD) OUTPUT(*OUTFILE) OUTFILE(QTEMP/BIB) OUTMBR(*FIRST *ADD);
SELECT * FROM QTEMP.BIB WHERE ODAPAR = 'CHGDFT';

Il suffit désormais de copier les instructions ci-dessus et de les coller dans l’exécuteur de scripts SQL de ACS, puis de sélectionner le tout (CTRL + A) et d’exécuter (CTRL + R).

Résultat de la requête sur cette partition. Cette fois on trouve bien la commande CRTBNDRPG.


Une précision pour l’exécution des ces instructions. Par défaut, ACS stoppe l’exécution des instructions dès qu’il trouve une erreur.


Si tous les produits de la liste ci-dessus ne sont pas installés sur le système analysé, alors il y aura arrêt de l’exécution puisque la requête ne trouvera pas toutes les bibliothèques concernées. Pour y remédier, il faut soit retirer les bibliothèques non présentes avant d’exécuter le flot d’instructions, soit décocher l’option “Arrêt en cas d’erreur” avant de lancer les commandes.


Cette méthode fonctionne sur toutes les partitions IBM i 6.1 à 7.4, quels que soient les niveaux de Technology Refresh, de cumulative et de groupes de PTF.

Toutefois, depuis les versions récentes, il est possible d’utiliser directement un service IBM i :

SELECT * FROM TABLE(QSYS2.OBJECT_STATISTICS('*ALL', '*CMD')) WHERE APAR_ID = 'CHGDFT';

On obtient le même résultat qu’avec la liste d’instructions évoquées précédemment.

Mais pour cela, il faut disposer de l’un des niveaux minimums suivants (pas de support pour la 7.2) :

  • IBM i 7.3 Technology Refresh 7 avec le groupe Db2 SF99703 Level 16
  • IBM i 7.4 Technology Refresh 1 avec le groupe Db2 SF99704 Level 4

Dernière précision, ces méthodes permettent de retrouver les commandes CL IBM qui ont été modifiées mais elles ne fournissent que la liste et pas le détail des modifications qui ont pu être apportées. Une fois que l’on dispose de la liste, il faut ensuite comparer tous les paramètres des commandes pour savoir quels sont ceux qui ont été changés.

Rappelons que cette vérification est un point indispensable avant tout changement de version ou toute migration vers un autre système sous peine de perdre un paramétrage spécifique lié à l’environnement du système.