Utilisation de QSHELL sur IBM iSeries
Sommaire :
- Lancement du SHELL iSeries |
- Mon petit .profile |
- Schéma d’une commande CL utilisant QSHELL |
- SQL facile sur AS/400-iSeries avec QSHELL |
- Java et QSH (création d’un fichier zip sur AS/400-iSeries)|
- Valeurs d’environnement |
- Création d’un script (utilisation d’EDTF) |
- Exemple : script interactif (recherche dans des membres sources) |
- Applications diverses |
Lancement du SHELL iSeries
Commandes : QSH ou STRQSH
Mon petit .profile
Chacun a remarqué le mot-clef HOMEDIR dans la commande CRTUSRPRF (Créer un profil utilisateur). Cette zone se voit assigner par défaut la valeur /home/[usrprf]. Elle désigne le répertoire IFS personnel de l’utilisateur. Ce chemin doit néanmoins être créé (faire un MKDIR '/home/mon_userid'). On peut choisir un autre emplacement, du moment qu’on y a accès.
Le .profile est un fichier lu par le système au démarrage du shell, il permet de modifier les valeurs d’environnement avec la commande export (cf plus bas).
Cela étant dit, dans /home/mon_userid, je crée un fichier nommé .profile qui contient ce qui suit.
PS1='$PWD $' export PS1
PWD est une commande QSHELL qui signifie « print working directory » et affiche le répertoire en cours. PS1 est la « primary prompt string » (chaîne première du prompt). EXPORT permet d’attribuer une valeur à une variable d’environnement.
Pour créer le fichier, utiliser EDTF — ou tout autre moyen (cf infra) — avec la simple commande : EDTF '/home/monuserid/.profile'. Le shell affichera désormais le répertoire en cours avant le prompt :
QSH Command Entry /home/mon_userid $ ===> __________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ _______________________________________________________________________________ F3=Exit F6=Print F9=Retrieve F12=Disconnect F13=Clear F17=Top F18=Bottom F21=CL command entry
Schéma d’une commande CL utilisant QSHELL
Commande qui permet de passer une suite de paramêtres :
CMD PROMPT('Titre de l''action') PARM KWD(PARA1) TYPE(*NAME) PROMPT('Action')
Création de la commande
Option ou commande ===> CRTCMD BIBLIO/NOMCMD BIBLIO/NOMCL SRCFILE(BIBLIO/QCMDSRC) SRCMBR(NOMCMD) TEXT('Texte explicatif')
CL :
PGM PARM(&PARA1) DCL VAR(&PARA1) TYPE(*CHAR) LEN(10) DCL VAR(&CMD) TYPE(*CHAR) LEN(80) CHGVAR VAR(&CMD) + VALUE('/QIBM/ProdData/etc.' + *BCAT &PARA1 etc.) /* Redirection des sorties */ DLTF FILE(QTEMP/STDOUT) MONMSG CPF2105 CRTPF FILE(QTEMP/STDOUT) RCDLEN(128) OVRDBF STDOUT QTEMP/STDOUT QSH CMD(&CMD) DLTOVR STDOUT ENDPGM
SQL facile sur AS/400-iSeries avec QSHELL
Finies les limitations des CL et les complications des RPG. Démonstration interactive :
- Pour avoir de la place sur l’écran sous PDM, on a actionné [F10] puis [F11]
- Noter le point au lieu de la barre oblique (slash) qui sépare le nom de bibliotèque (« collection ») du nom du fichier (« table »).
- Au lieu d’être affichée, la sortie est dirigée vers un fichier texte de l’IFS.
Entrée de commandes ZORGLUB Niveau de demande: 4 Tapez une commande, puis appuyez sur ENTREE. ===> qsh cmd('db2 "SELECT * FROM uhrbibl.p0gccmde______________________________ ____________________WHERE_(cdrt01_=_''83359''_or_cdrt02_=_''83359''_or_cdrt03_=_ _______________________''83359''_or_cdrt04_=_''83359''_or_cdrt05_like_''8335%'') ____________________ORDER BY CDSIMP"____________________________________________ ____________________>_/home/guebey/tmp/sortie.txt')_____________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ ________________________________________________________________________________ _______________________________________________________________________________ F3=Exit F4=Invite F9=Rappel F11=Ecran partiel F12=Annuler F13=Informations techniques F16=Menu principal
Comme toutes les commandes QSHELL, DB2 désigne ici un lien symbolique objet AS/400 de type *PGM, en l’espèce vers QZDFMDB2.
Affichage de la sortie :
Option ou commande
===> dspf '/home/guebey/tmp/sortie.txt'
F3=Exit F4=Invite F9=Rappel F12=Annuler F13=Informations techniques
F23=Définir menu initial
Donne :
Browse : /home/guebey/tmp/sortie.txt Record : 1 of 11 by 18 Column : 1 379 Control : ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 ************Beginning of data************** CDFSUP CDNCDE CDNABO CDCSIP CDCCYC CDCFIL CDCNIE CDDSIG CDDPAI ------- --------- --------- ------- ------- ------- ------- ---------- --------- 585738 432423 3 5 99 0 20040831 585740 432425 3 3 99 0 20040831 591090 436099 3 5 99 0 20040907 607087 398878 3 99 0 20041109 663232 480303 3 99 0 20060127 5 RECORD(S) SELECTED. ************End of Data******************** F3=Exit F10=Display Hex F12=Cancel F15=Services F16=Repeat find F19=Le
Rappel : sur l’AS/400, les données seront toujours lues correctement, parce que le système tient compte de la page de code (ou CCSID) des données. Mais dans un partage réseau vu depuis un PC, il peut arriver que s’affiche quelque-chose comme ce qui suit :
%ÒÖÆÉðñ@@ÒÖÕÁÂÖ@@@@ÒÖàÖÙÉ@@ÒÖà×ÙÅ@@ÒÖÕÓÕÇ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ÓÕÇ@@@@@@@@@@@@@@@@@@@@@@@@@ÒÖàÁÄÙ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÒÖàÁÄò @@@@@@@@@@@@@@@@@@@@@@@@@@@ÒÖÁÕÙä@@ÒÖàÂÉâ@@ÒÖÓÙäÅ@@@@@@@@@@@@@@@@@@@@@@@@ @@@ÒÖÓàÖÔ@@@@@@@@@@@@@@@@@@@@@@@@@@@ÒÖà×Öâ@@ÒÖÁÕÁÉ@@ÒÖÁ×àÖ@@ÒÖÁÔÄà@@ÒÖàâÉ
Il conviendra donc de gérer l’encodage du fichier récepteur, ce qui (avec CHGATR, ou TOUCH, ou SETCCSID...) est l’enfance de l’art si l’on se réfère à la page ad-hoc. [http://www.dg77.net/tekno/as400/ccsid.htm#ifs]
Comment sortir dans un fichier la LISTE DES MEMBRES d'une bibliothèque avec leur TAILLE ?
QSH CMD('db2 "SELECT SYSTEM_TABLE_SCHEMA, SYSTEM_TABLE_NAME, SYSTEM_TABLE _MEMBER, DATA_SIZE from qsys2.syspstat where sys_dname=''mabiblio''" > /home/guebey/tmp/sortie.txt ')
Mieux (en format csv) :
QSH CMD('db2 "SELECT SYSTEM_TABLE_SCHEMA,'';'', SYSTEM_TABLE_NAME,'';'', SYSTEM_TABLE_MEMBER, '';'', DATA_SIZE from qsys2.syspstat where sys_dname=''mabiblio''" > /home/guebey/tmp/sortie.txt ')
Java et QSH — zipage/compression de fichiers
Dans le QSHELL une classe java peut être créée (commande javac) ou lancée (commande java). Voir un exemple dans la page Mini-tutorial Java, section : Création d’un premier programme Java sur IBM AS400 / iSeries. [http://www.dg77.net/tekno/java/index.htm#as400]
QSHELL permet en effet l’utilisation des commandes et outils du Developper Kit for Java : ajar, appletviewer, apt, extcheck, idlj, jar, jarsigner, javac, javadoc, javah, javap, keytool, native2ascii, orbd, pack200, policytool, rmic, rmid, rmiregistry, serialver, servertool, tnameserv, unpack200.
Voici un petit CL pour « ziper » (comprimer) les fichiers d’un répertoire IFS, utilisant ajar.
/* Ce CL a pour fonction le "zipage" de fichiers de l'IFS */ /* */ /* Utilisation de l'outil ajar en environnement QSHELL */ /* ajar est aux fichiers zip ce que jar est aux jar... */ /* */ PGM &NOMDIR DCL &NOMDIR *CHAR 0020 /* Nom du sous-répertoire à ziper */ DCL &DIR *CHAR 2000 /* Chemin complêt des fichiers à lire. */ DCL &CMD *CHAR 2000 /* Commande QSHELL à lancer */ CHGVAR &DIR ('/racine/' *tcat &NOMDIR) CHGCURDIR &DIR /* Positionne dans le bon emplacement */ MONMSG CPF0000 CHGVAR &CMD ('ajar -cM' *BCAT '/racine/SORTIE.zip' *BCAT '*.*') OVRDBF STDOUT QTEMP/STDOUT QSH CMD(&CMD) MONMSG CPF0000 DLTOVR STDOUT ENDPGM
Valeurs d’environnement
Généralités et export
Dans la page sur Java référencée ci-dessus, on trouve l’utilisation d’une valeur d’environnement pour enregistrer le CLASSPATH. La méthode indiquée utilise le QSHELL interactif. On peut obtenir le même résultat avec la commande SHELL export.
export CLASSPATH=${CLASSPATH}:/home/monrep/class/outils.jar
Le précédent export ajoute à la valeur CLASSPATH en cours (précédant le « : ») un chemin supplémentaire.
Le .profile est un moyen d’initialiser les valeurs d’environnement. Voir l’exemple ci-dessus.
Traitement silencieux
Ici on gère les valeurs d’environnement pour ne pas avoir de sortie des messages d’information. Noter l’enchaînement des commandes, séparées de point-virgules (« ; »).
PGM /* POUR NE PAS AVOIR DE SORTIE A L ECRAN */ RMVENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) MONMSG MSGID(CPFA981) ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(NONE) /* EXECUTE LES COMMANDES QSHELL */ STRQSH CMD('cd /qibm/UserData/WebSphere/WASbackups;/qibm/U+ serData/WebSphere/AppServer/V6/ND/profiles/NUV/bin/backupC+ onfig -username admin -password admin1 -nostop;/qibm/UserData+ /WebSphere/AppServer/V6/ND/profiles/NUVDmgr/bin/backupConfig + -username admin -password admin1 -nostop) /* RESTAURE LES VALEURS PAR DEFAUT */ CHGENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(STDOUT) ENDPGM
Création d’un script
Ci-dessous, utilisation d’EDTF
On peut aussi éditer sur PC puis transférer (copier-coller ou glisser-déposer (drag and drop) via iSeries-Access ; ou encore éditer directement via un « lecteur réseau » si on en dispose.
Fin ===> EDTF STMF('/home/mon_nom/lstmbr') F21=Afficher instructions/touches
EDTF s’utilise à-peu-près comme PDM.
Edit File: /home/mon_nom/lstmbr Record : 1 of 44 by 8 Column : 1 67 by 74 Control : CMD ....+....1....+....2....+....3....+....4....+....5....+....6....+....7 ___ # SCRIPT DE DEMONSTRATION ___ # ======================= ___ # Recherche d'une chaine de caractères dans des membres de fichiers ___ # - La liste des membres trouvés est affichée ___ # - et est sortie dans un fichier ___ # ___ echo "--- LISTE DE MEMBRES D'UNE BIBLIOTHEQUE ---------------" ___ echo "Entrer le nom de la bibliothèque" ___ read nombib ___ if test ${nombib} = ""; then ${nombib} = "*" ___ else if test -d /QSYS.LIB/${nombib}.LIB; then echo " " ___ else echo "Problème avec la bibliothèque "${nombib} ___ fi ___ fi F2=Save F3=Save/Exit F12=Exit F15=Services F16=Repeat find F17=Repeat change F19=Left F20=Right
Exemple : script interactif (recherche dans des membres sources)
Noter ci-dessous l’utilisation de :
- read : attend une entrée.
- test en différentes options : -e, -d..
- system : lance une commande AS/400-iSeries
- tee : sortie simultanée dans plusieurs directions (ici stdout et un fichier.
# SCRIPT DE DEMONSTRATION # ======================= # Recherche d'une chaine de caractères dans des membres de fichiers # - La liste des membres trouvés est affichée # - et est sortie dans un fichier # echo "--- LISTE DE MEMBRES D'UNE BIBLIOTHEQUE ---------------" echo "Entrer le nom de la bibliothèque" read nombib if test ${nombib} = ""; then ${nombib} = "*" else if test -d /QSYS.LIB/${nombib}.LIB; then echo " " else echo "Problème avec la bibliothèque "${nombib} fi fi echo "Entrer le nom du fichier source" read nomfic if test ${nomfic} = ""; then ${nomfic} = "*" else if test -e /QSYS.LIB/${nombib}.LIB/${nomfic}.FILE; then echo " " else echo "Problème avec le fichier "${nomfic} fi fi echo "Entrer l'argument de recherche (facultatif)" read chaine echo "--- Sortie dans un fichier (facultatif) --------------" echo "Entrer le nom de la bibliothèque" read bibout if test $bibout = ""; then echo " " else if test -d /QSYS.LIB/${bibout}.LIB; then echo " " else echo "Problème pour la bibliothèque "${bibout} fi fi echo "Entrer le nom du fichier " read ficout if test $ficout = ""; then echo " " else if test -e /QSYS.LIB/${bibout}.LIB/${ficout}.FILE then echo " " else echo "Le fichier "${ficout} " va être créé" system -q "CRTPF "$bibout"/"$ficout" RCDLEN(256)" fi fi echo " -> Traitement en cours" if test $chaine != "" then egrep -l ${chaine} /qsys.lib/${nombib}.LIB/${nomfic}.FILE/* \ | tee /QSYS.LIB/${bibout}.lib/${ficout}.file/${ficout}.mbr else ls -A /qsys.lib/${nombib}.LIB/${nomfic}.FILE/* \ | tee /QSYS.LIB/${bibout}.lib/${ficout}.file/${ficout}.mbr fi echo " -> Traitement terminé"
Applications diverses
Références diverses
Cf la page Extraction de fichiers sur AS/400-iSeries puis envoi par FTP [http://www.dg77.net/tekno/as400/cl_sqlftp.htm].
Utilisation directe sur AS/400
Comment lancer la commande QSHELL en ligne de commande iSeries (ou dans un CL). Exemple pour la commande : sed -e "s/ //g" (voir plus bas)
QSH CMD('sed -e "s/ //g"')
Sed et iconv, suppression des caractères espace et maîtrise de l’encodage.
sed -e "s/ //g" remplace les espaces par null.
Attention : la sortie d’une utility QSHELL est codée dans le CCSID de la session. D’où l’utilisation de iconv : le fichier IFS lu en entrée est le résultat d’un CPYTOIMPF qui avait créé un fichier au codage Windows, mais le sed le remet en EBCDIC (1147). L’utilitaire iconv permet de retomber dans l’encodage voulu (1252).
===> sed -e "s/ //g" /tmp/SCH_PGC_tmp.csv | iconv -f 1147 -t 1252 > !! SCH_PGC_tmp20070714.csv
Grep et datarea, comptage
On compte (option -c) le nombre d’occurences d’une chaîne dans un membre source. Le résultat obtenu est mis (datarea option -w) dans la foulée dans une zone de données (DATA AREA) AS/400.
===> grep -c "226 Transfer OK" /QSYS.LIB/BIBLIO_SRC.LIB/QFTPSRC.FILE/SCH_PGC_OU.MBR | datarea -w /QSYS.LIB/TRAVAIL.LIB/SCH_tmp.dtaara
Grep, liste de membres contenant une chaîne de caractères
Sans l’option -l, GREP ajoute la ligne où se trouve la chaîne de recherche à chaque enregistrement sorti. Noter la sortie vers un fichier avec > au lieu de la sortie standard.
===> grep -l 'CHAINE' /QSYS.LIB/biblio.LIB/QCLSRC.FILE/* > /home/monrepertoire/tmp/listecl.txt
Pour afficher le fichier sorti :
===> cat /home/monrepertoire/tmp/listecl.txt
Si on veut récupérer les données sur PC, ne pas oublier la conversion :
===> grep 'XYKN' /QSYS.LIB/BIBSRC.LIB/QddsSRC.FILE/* | iconv -f 297 -t 1252 > /home/mabiblio/tmp/xykn_dds.txt
Find + basename, liste de membres sources
Utilise basename pour éliminer le PATH ({}) et le suffixe (.MBR, attention : le suffixe est case sensitive). Noter aussi le point-virgule avec ESCAPE (\) à la fin de la commande lancée par -exec.
===> find /QSYS.lib/mabbiblio.lib/qclsrc.file/* -exec basename {} .MBR \;
Find, liste de fichiers
Affichage depuis un autre système grâce à QfileSvr.400.. Voir la page Transferts de fichiers sur iSeries [http://www.dg77.net/tekno/as400/transfer.htm#ifs].
===> find /QfileSvr.400/SYSTEM2/QSYS.LIB/OLCDTA.LIB -name "*.FILE" -exec basename {} .FILE \;
Find + rm, suppression périodique de fichiers
Suppression d’une série de fichiers dont la dernière modification date de plus de 30 jours
===> find /QIBM/UserData/OS400/MGTC/service -name "*.log" -mtime +30 -exec rm -f {} ;
Affichage des sous-répertoires d’une arborescence
===> ls -R /home/guebey | grep ''/'' > /tmp/div.txt
Explications :
- ls avec option -R lit récursivement les sous-répertoires.
- grep '/' et sans option ne prend que les lignes ayant un slash.
- On met la sortie dans un fichier div.txt au lieu de l’afficher
Pour voir la sortie, sous QSHELL : cat /tmp/div.txt. DSPLNK '/tmp/div.txt' permet d’afficher la même chose. Résultat :
/home/guebey/PC: /home/guebey/PC/DOC: /home/guebey/PC/Trav: /home/guebey/PC/bin: /home/guebey/pdf: /home/guebey/tmp:
Pour enlever les ennuyeux ":" en fin de ligne, je rajoute un sed : ls -R /home/guebey | grep ''/'' | sed -e "s/://g" > /tmp/div.txt