Je suis VTOM
#craquage
(voir plus) Je suis VTOM#craquage
(voir plus) Je suis VTOMYou know .personalport_rc
? moi non plus, jusqu’à il y a peu de temps.
C’est bien pratique pour :
Il est à placer dans le répertoire home du user d’admin vtom.
On fait correspondre les ports :
[ports]
vtserver:<le nom que je veux que j'aurais mis dans /etc/services>
vtsgbd:<le nom que je veux que j'aurais mis dans /etc/services>
etc etc pour tous les ports VTOM que je veux
J’ai un serveur VTOM classique, les ports sont :
# ---------------------
# Demons tcp Visual TOM
# ---------------------
tomDBd 30001/tcp
bdaemon 30004/tcp
vtserver 30007/tcp
vtnotifier 30008/tcp
vtsgbd 30009/tcp
vthttpd 30080/tcp
vtmanager 30000/tcp
Je veux passer mon serveur en maintenance (pour que personne ne s’y connecte par exemple). Je rajoute cette ligne dans /etc/services
:
vtserverm 30107/tcp # port de maintenance vtom
Je prépare 2 fichiers .personalport_rc.origin et .personalport_rc.maint (les noms n’ont pas d’importance) :
~vtom/.personalport_rc.origin et je fais correspondre le vtserver au service d'origine vtserver
[ports]
vtserver:vtserver
~vtom/.personalport_rc.maint et je fais correspondre le vtserver au service de maintenance vtserverm qui pointe sur un port différent
[ports]
vtserver:vtserverm
Le plus évident pour bien voir que ça fonctionne, c’est la commande vtping
.
En temps normal, vtping
:
vtom@cedfc0a2778f:~$ vtping
[serveur locaux (172.17.0.2)]
vtsgbd vtsgbd:30009 actif
vtserver vtserver:30007 actif
vtnotifier vtnotifier:30008 actif
dserver tomDBd:30001 actif
vtmanager vtmanager:30000 arrete
bdaemon bdaemon:30004 arrete
vthttpd vthttpd:30080 actif
[moteurs]
tengine exploitation arrete
...
Par exemple, je copie ~vtom/.personalport_rc.maint
sur ~vtom/.personalport_rc
, je fais vtping
:
je vois que le vtserver a bien été pris en compte avec le port de maintenance
vtom@cedfc0a2778f:~$ vtping
[serveur locaux (172.17.0.2)]
vtsgbd vtsgbd:30009 actif
vtserver vtserver:30107 arrete
vtnotifier vtnotifier:30008 actif
dserver tomDBd:30001 actif
vtmanager vtmanager:30000 arrete
bdaemon bdaemon:30004 arrete
vthttpd vthttpd:30080 actif
En gros, lors de mes phases de maintenance :
stop_servers
~vtom/.personalport_rc.maint
sur ~vtom/.personalport_rc
start_servers
stop_servers
~vtom/.personalport_rc.origin
sur ~vtom/.personalport_rc
start_servers
J’ai une installation classique avec un user vtom. J’ai les services classiques dans /etc/services
:
# ---------------------
# Demons tcp Visual TOM
# ---------------------
tomDBd 30001/tcp
bdaemon 30004/tcp
vtserver 30007/tcp
vtnotifier 30008/tcp
vtsgbd 30009/tcp
vthttpd 30080/tcp
vtmanager 30000/tcp
J’installe un autre serveur VTOM sur le même serveur avec le user vtomd
par exemple :
# pour mieux me repérer je mets le même nom de service qu'à l'origine et je rajoute "d" à la fin, comme vtom"d" de mon user
# ---------------------
# Demons tcp Visual TOM
# ---------------------
tomDBdd 40001/tcp
bdaemond 40004/tcp
vtserverd 40007/tcp
vtnotifierd 40008/tcp
vtsgbdd 40009/tcp
vthttpdd 40080/tcp
vtmanagerd 40000/tcp
Et je personnalise le .personalport_rc
dans le répertoire home de vtomd
:
(vtomd)/usr/vtomd$ cat .personalport_rc
[ports]
tomDBd:tomDBdd
bdaemon:bdaemond
vtserver:vtserverd
vtmanager:vtmanagerd
vtnotifier:vtnotifierd
vtsgbd:vtsgbdd
vthttpd:vthttpdd
Merci à Serge D, pour l’inspiration et l’astuce que je ne connaissais pas.
unix : si ce n’est à l’intérieur des scripts même, les variables d’environnement sont souvent regroupées à un seul endroit dans les fichiers de démarrage (et sont disponibles pour l’ensemble des scripts)
home
des utilisateurs de soumission selon les shells :
.profile
.cshrc
.zprofile
les variables d’environnement exportées sur la session de l’utilisateur d’administration (en général vtom
) sont prises en compte lors du démarrage du client VTOM (adminc
ou start_client
)
Résultat : j’ai des gens “bien intentionnés” qui m’ont surchargé le .profile
du user vtom
avec des variables d’env qui n’avaient rien à faire là
Au cas où, il faut bien recharger le profil par ex. . .profile
avant de relancer le client si vous avez apporté des modifications sur le .profile de vtom
Merci à JOEY de m’avoir inspriré ! :)
Sur Outlook, pour un mail au format HTML avec des liens anchor de type <a href="#versid">...
vers <div id="versid">...
ne fonctionne pas chez moi.
Seul le href #top
ou #haut
selon la langue fonctionne (sans même avoir de conteneur avec cet id).
Ce qui fonctionne dans mon contexte, c’est de remplacer (ou d’ajouter) un tag <a name="versid"></a>
juste avant le conteneur de destination.
Ca donne :
<a href="#bonjour">lien classique</a>
<p>du texte</p>
...
<a name="bonjour"></a>
<div id="bonjour">
mon div etc.
</div>
Recherche dans une feuille qui check si une de ces colonnes (test de chaque ligne d’une colonne IP Adresse) est présente dans deux feuilles différentes (correspondance adresse)
Les formules présentes pourraient être utile pour :
=SI.NON.DISP(
SI.NON.DISP(
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
LastExec!$S:$S;
1;
FAUX
);
RECHERCHEV(
GAUCHE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
Tableau2[[#Tout];[IP]:[IP]];1;FAUX
)
);
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
DROITE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
LastExec!$S:$S;
1;
FAUX
);
RECHERCHEV(
GAUCHE(
DROITE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
)
);
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
DROITE(
DROITE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
LastExec!$S:$S;
1;
FAUX
);
RECHERCHEV(
GAUCHE(
DROITE(
DROITE(
SUBSTITUE([@adresses];"0.0.0.0";"");
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";""))
);
CHERCHE(CAR(10);SUBSTITUE([@adresses];"0.0.0.0";"")) - 1
);
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
)
)
=SI.NON.DISP(
SI.NON.DISP(
RECHERCHEV(
[@adresses];
Tableau1[[#Tout];[IP]:[IP]];
1;
FAUX
);
RECHERCHEV(
[@adresses];
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
);
SI.NON.DISP(
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
[@adresses];
CHERCHE(CAR(10);[@adresses]) - 1
);
Tableau1[[#Tout];[IP]:[IP]];
1;
FAUX
);
RECHERCHEV(
GAUCHE(
[@adresses];
CHERCHE(CAR(10);[@adresses]) - 1
);
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
);
SI.NON.DISP(
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(
CAR(10);
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
)
) - 1
);
Tableau1[[#Tout];[IP]:[IP]];
1;
FAUX
);
RECHERCHEV(
GAUCHE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(
CAR(10);
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
)
) - 1
);
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
);
SI.NON.DISP(
RECHERCHEV(
GAUCHE(
DROITE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(CAR(10);DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
))
);
CHERCHE(
CAR(10);
DROITE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(CAR(10);DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
))
)
) - 1
);
Tableau1[[#Tout];[IP]:[IP]];
1;
FAUX
);
RECHERCHEV(
GAUCHE(
DROITE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(CAR(10);DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
))
);
CHERCHE(
CAR(10);
DROITE(
DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
);
CHERCHE(CAR(10);DROITE(
[@adresses];
CHERCHE(CAR(10);[@adresses])
))
)
) - 1
);
Tableau2[[#Tout];[IP]:[IP]];
1;
FAUX
)
)
)
)
)
Des fois, j’ai des questions en direct par e-mail. Je me dis que ça pourrait être bien de poster les questions / réponses.
Unlock a locked date in command line is not possible, and should stay a human action. If you ask yourself how to automate and unlock a locked date (or all) without an human action, may be your job(s) should not lock the date in the first place (in jobs’s definition).
Of course you can always unlock a locked date by setting all jobs which are blocking this date to OK.
You can list all locked date with this command :
tlist blocage
Or check the status of a date :
tchkdate /nom="your_datename"
Then loop over all blocking jobs and set to OK :
vtom@044d119e1768:/mnt/workspace$ vtaddjob /nom="exploitation/appli_test/job1" /status="te"
Modification du traitement exploitation/appli_test/job1 terminee (27ms).
tlist [-f <env>[/<app>[/<job>]]] jobs
should do the trick.
Something like that :
tlist jobs | sort -k"2,2" -u | grep -w "your_date"
sort -k"2,2" -u to sort on applications and get unique row for an application
grep -w "your_date" to filter with your specific date
vtom@044d119e1768:~$ tlist -f exploitation jobs | sort -k"2,2" -u | grep -w "date_exp"
exploitation appli_test job1 client_local date_exp
Also, you can do a csv list of whatever column you want with a vtexport and an preformatted xsl file.
First compile the Stylizer.java class : javac Stylizer.java
Export your VTOM base in XML :
vtexport -x [-f <env>[/<app>[/job]]] > /somepath/your_vtexport.xml
Filter the XML with the XSL file : java Stylizer filter_env_app_date.xsl your_vtexport.xml
vtom@044d119e1768:/mnt/workspace$ javac Stylizer.java
vtom@044d119e1768:/mnt/workspace$ ls
Stylizer.class Stylizer.java
vtom@044d119e1768:/mnt/workspace$ java Stylizer filter_env_app_date.xsl /var/tmp/vtexport.xml
exploitation£appli_test£date_exp£
Code couleur des statuts dans VTOM.
R = ENCOURS #05FAFA
X = ENDIFFICULTE #FFC800
W = AVENIR #FAFF14
F = TERMINE #14FF14
E = ENERREUR #FA0000
D = DEPLANIFIE #C3C3C3
U = NONPLANIFIE #FAFAFA
{
"R" : {"rvb":"5,250,250","nom":"ENCOURS"},
"X" : {"rvb":"255,200,0","nom":"ENDIFFICULTE"},
"W" : {"rvb":"250,255,20","nom":"AVENIR"},
"F" : {"rvb":"20,255,20","nom":"TERMINE"},
"E" : {"rvb":"250,0,0","nom":"ENERREUR"},
"D" : {"rvb":"195,195,195","nom":"DEPLANIFIE"},
"U" : {"rvb":"250,250,250","nom":"NONPLANIFIE"}
}
Et la column vtstatus dans la table vt_stats_job : (index de 0 à 6)
let Status = ["", "AVENIR ", "ENCOURS", "TERMINE", "ENERREUR", "DEPLANIFIE", "NONPLANIFIE"]
# mode d'exécution
let VTOMModeExec = ["", "Exéc", "Simu", "Test", "Stop", "Job"]
Je ne sais pas s’il existe une raison justifiant le fait de faire du sftp non sécurisé (mot de passe en clair, sans certificat SSL) mais des fois, il ne faut pas trop chercher à comprendre.
Donc sachez que si on vous dit, “plus de FTP, il faut faire du SFTP” et qu’on vous dit, “ah non, impossible de mettre en place des clés privées, publiques”, vous pouvez scripter du sftp avec curl avec le user / mot de passe !
# la racine de connexion du user
curl -k -u user:mdp sftp://host
# un répertoire en particulier (ne pas oublier le dernier /)
curl -k -u user:mdp sftp://host/MyDir/
# affiche le contenu du fichier à l'écran
curl -k -u user:mdp sftp://host/monFichier
# récupérer un fichier
curl -k -u user:mdp sftp://host/monFichier -o /monRep/monFichier
-v | mode verbose, pratique pour debug
-u user:mdp | pour l'authentification
sftp://@IP:port | protocole peut être sftp, ftp, http par exemple
-Q "CMD dir/file" | exécution de la commande sur le fichier (on part de la racine de connexion user)
-k ou --insecure | (SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers
| problème résolu de "curl: (51) SSL peer certificate or SSH remote key was not OK"
-o dir/file | redirige la sortie dans le fichier dir/file
# delete
curl -u user:mdp ftp://host -Q 'DELE MyDir/FileTodelete'
# rename
curl -u user:mdp ftp://host -Q 'RNFR MyDir/FileToRename' -Q 'RNTO MyDir/FileRenamed'
# delete
curl -k -u user:mdp sftp://host -Q 'rm MyDir/FileTodelete'
# rename
curl -k -u user:mdp sftp://host -Q 'rename MyDir/FileToRename MyDir/FileRenamed'
# on peut cumuler la commande + le listage (attention, par défaut, la commande est effectuée avant)
# supprimer le rep' /var/tmp/MyDir et lister le contenu de /var/tmp/
curl -k -u user:mdp sftp://host/var/tmp/ -Q 'rmdir /var/tmp/MyDir'
man curl
-Q, --quote <command>
(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote commands are sent BEFORE the transfer takes place (just
after the initial PWD command in an FTP transfer, to be exact). To make commands take place after a successful transfer, prefix them
with a dash '-'. To make commands be sent after curl has changed the working directory, just before the transfer command(s), prefix
the command with a '+' (this is only supported for FTP). You may specify any number of commands. If the server returns failure for one
of the commands, the entire operation will be aborted. You must send syntactically correct FTP commands as RFC 959 defines to FTP
servers, or one of the commands listed below to SFTP servers. This option can be used multiple times. When speaking to an FTP server,
prefix the command with an asterisk (*) to make curl continue even if the command fails as by default curl will stop at first failure.
SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands itself before sending them to the server. File names
may be quoted shell-style to embed spaces or special characters. Following is the list of all supported SFTP quote commands:
chgrp group file
The chgrp command sets the group ID of the file named by the file operand to the group ID specified by the group operand. The
group operand is a decimal integer group ID.
chmod mode file
The chmod command modifies the file mode bits of the specified file. The mode operand is an octal integer mode number.
chown user file
The chown command sets the owner of the file named by the file operand to the user ID specified by the user operand. The user
operand is a decimal integer user ID.
ln source_file target_file
The ln and symlink commands create a symbolic link at the target_file location pointing to the source_file location.
mkdir directory_name
The mkdir command creates the directory named by the directory_name operand.
pwd The pwd command returns the absolute pathname of the current working directory.
rename source target
The rename command renames the file or directory named by the source operand to the destination path named by the target oper‐
and.
rm file
The rm command removes the file specified by the file operand.
rmdir directory
The rmdir command removes the directory entry specified by the directory operand, provided it is empty.
symlink source_file target_file
See ln.
Merci JM F. pour celle-là ;)
export LIBPATH=:/usr/lib:$LIBPATH
-k ou --insecure
Sympa pour les API avec un retour JSON par exemple : voir mon article sur le WebAccess
et pour plein d’autres fonctionnalités sympa (comme récupérer les entêtes d’une requête HTML) client URL
J’ai un tableau d’objets, et je veux récupérer un tableau de valeurs uniques d’objets ayant le même attribut.
let _distinctUniqueValuesInArray = (arr, prop) => arr.map(obj => obj[prop]).filter((v, i, a) => a.indexOf(v) == i)
var monArray = [
{"VTENVNAME":"ENV1","VTDOMAINE":"MONDOMAINE25","NB_JOBS_NON_STATS":"15"},
{"VTENVNAME":"ENV2","VTDOMAINE":"MONDOMAINE15","NB_JOBS_NON_STATS":"58"},
{"VTENVNAME":"ENV2","VTDOMAINE":"MONDOMAINE35","NB_JOBS_NON_STATS":"18"},
{"VTENVNAME":"ENV2","VTDOMAINE":"MONDOMAINE25","NB_JOBS_NON_STATS":"50"},
{"VTENVNAME":"ENV5","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"2"},
{"VTENVNAME":"ENV5","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"10"},
{"VTENVNAME":"ENV7","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"81"},
{"VTENVNAME":"ENV7","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"47"},
{"VTENVNAME":"ENV7","VTDOMAINE":"MONDOMAINE16","NB_JOBS_NON_STATS":"71"},
{"VTENVNAME":"ENV8","VTDOMAINE":"MONDOMAINE25","NB_JOBS_NON_STATS":"45"},
{"VTENVNAME":"ENV8","VTDOMAINE":"MONDOMAINE15","NB_JOBS_NON_STATS":"31"},
{"VTENVNAME":"ENV8","VTDOMAINE":"MONDOMAINE35","NB_JOBS_NON_STATS":"62"},
{"VTENVNAME":"ENV13","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"2"},
{"VTENVNAME":"ENV13","VTDOMAINE":"MONDOMAINE16","NB_JOBS_NON_STATS":"2"},
{"VTENVNAME":"ENV13","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"2"},
{"VTENVNAME":"ENV14","VTDOMAINE":"MONDOMAINE16","NB_JOBS_NON_STATS":"56"},
{"VTENVNAME":"ENV14","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"29"},
{"VTENVNAME":"ENV14","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"77"},
{"VTENVNAME":"ENV15","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"164"},
{"VTENVNAME":"ENV15","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"90"},
{"VTENVNAME":"ENV15","VTDOMAINE":"MONDOMAINE16","NB_JOBS_NON_STATS":"139"},
{"VTENVNAME":"ENV16","VTDOMAINE":"MONDOMAINE16","NB_JOBS_NON_STATS":"113"},
{"VTENVNAME":"ENV16","VTDOMAINE":"MONDOMAINE36","NB_JOBS_NON_STATS":"123"},
{"VTENVNAME":"ENV16","VTDOMAINE":"MONDOMAINE26","NB_JOBS_NON_STATS":"410"}
]
_distinctUniqueValuesInArray(monArray,"VTDOMAINE")
["MONDOMAINE25", "MONDOMAINE15", "MONDOMAINE35", "MONDOMAINE36", "MONDOMAINE26", "MONDOMAINE16"]
_distinctUniqueValuesInArray(monArray,"VTENVNAME")
["ENV1", "ENV2", "ENV5", "ENV7", "ENV8", "ENV13", "ENV14", "ENV15", "ENV16"]
Mon talbeau d’entrée étant constitué d’objets, et ne voulant qu’un tableau de valeurs pour une clé donnée, je créé un nouveau tableau avec map qui satisfait mes besoins.
(arr, prop) => arr.map(obj => obj[prop])
Array.prototype.filter() Array.prototype.indexOf()
Comme map() retourne un tableau, je peux l’enchainer avec filter()
Je ne retourne que les élements qui vérifient ma condition.
v (valeur), i (index), a (le tableau complet, ici monnouveautableau qui correspond à arr.map(obj => obj[prop]))
monnouveautableau.filter((v, i, a) => a.indexOf(v) == i)
En français : on boucle sur tous les élements de monnouveautableau et on retourne chaque élément dans un nouveau tableau si son index (i) correspond à l’index du premier élément (indexOf) de monnouveautableau qui a la valeur v.
Je ne sais pas si c’est français, mais j’me comprends !
https://stackoverflow.com/a/2784879
Array.prototype.deepSortAlpha= function(){
var itm, L=arguments.length, order=arguments;
var alphaSort= function(a, b){
a= a.toLowerCase();
b= b.toLowerCase();
if(a== b) return 0;
return a> b? 1:-1;
}
if(!L) return this.sort(alphaSort);
this.sort(function(a, b){
var tem= 0, indx=0;
while(tem==0 && indx<L){
itm=order[indx];
tem= alphaSort(a[itm], b[itm]);
indx+=1;
}
return tem;
});
return this;
}
monArr = [
["EVOLAN", "libéléEVOLAN2", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"],
["ALIS", "libéléALIS2", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "YES"],
["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "YES"],
["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse3", "endALIS", "NO"],
["EVOLAN", "libéléEVOLAN", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"],
["IAM", "libéléIAM1", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "YES"],
["IAM", "libéléIAM", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "YES"],
["OUI", "libéléOUI", "applOUI", "jobOUI", "domOUI", "caisse1", "endOUI", "YES"],
["ALIS", "libéléALIS2", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "NO"],
["EVOLAN", "libéléEVOLAN3", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"],
["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse1", "endALIS", "YES"],
["IAM", "libéléIAM3", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "NO"],
["IAM", "libéléIAM2", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "NO"],
["IAM", "libéléIAM", "applIAM", "jobIAM", "domIAM", "caisse2", "endIAM", "NO"]
]
monArr.deepSortAlpha(0,1,7)
(14) [Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8), Array(8)]
0:(8) ["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse3", "endALIS", "NO"]
1:(8) ["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "YES"]
2:(8) ["ALIS", "libéléALIS", "applALIS", "jobALIS", "domALIS", "caisse1", "endALIS", "YES"]
3:(8) ["ALIS", "libéléALIS2", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "NO"]
4:(8) ["ALIS", "libéléALIS2", "applALIS", "jobALIS", "domALIS", "caisse2", "endALIS", "YES"]
5:(8) ["EVOLAN", "libéléEVOLAN", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"]
6:(8) ["EVOLAN", "libéléEVOLAN2", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"]
7:(8) ["EVOLAN", "libéléEVOLAN3", "applEVOLAN", "jobEVOLAN", "domEVOLAN", "caisse1", "endEVOLAN", "YES"]
8:(8) ["IAM", "libéléIAM", "applIAM", "jobIAM", "domIAM", "caisse2", "endIAM", "NO"]
9:(8) ["IAM", "libéléIAM", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "YES"]
10:(8) ["IAM", "libéléIAM1", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "YES"]
11:(8) ["IAM", "libéléIAM2", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "NO"]
12:(8) ["IAM", "libéléIAM3", "applIAM", "jobIAM", "domIAM", "caisse1", "endIAM", "NO"]
13:(8) ["OUI", "libéléOUI", "applOUI", "jobOUI", "domOUI", "caisse1", "endOUI", "YES"]