La semaine dernière (enfin, c'était la semaine dernière quand j'ai commencé à rédiger cet article), nous avons reçu une demande au CAC : quelqu'un souhaitait créer une macro de commande qui lancerait une session Telnet pour se connecter à un système et y exécuter certaines commandes. Par exemple, la macro de commande test.cm se connecte à un hôte distant et exécute la macro de commande foo.cm.
&attach_input
telnet 192.168.77.128
mot de passe
foo.cm
|
|
Figure 1 – Commande Telnet : macro test.cm |
display_line display_system_usage
display_system_usage
display_line netstat -statistics -protocol tcp
netstat -statistics
display_line analyze_system -request_line 'stcp_meters -all -long' -quit
analyze_system -request_line 'stcp_meters' -quit
|
|
Figure 2 – foo.cm |
Malheureusement, Telnet n'est pas conçu pour s'exécuter dans une macro de commande et l'opération échoue.
test
telnet : erreur fatale - échec de tcgetattr
Erreur à la ligne 3 de test.
command_processor : Objet introuvable. password. Dans la macro de commande
%azvos#m17_mas>SysAdmin>Noah_Davids>test.cm
|
|
Figure 3 – L'exécution du fichier test.cm échoue |
Il existe toutefois plusieurs façons de se connecter automatiquement à un hôte distant puis d'y exécuter des commandes.
send_cmds.c :
J'ai écrit il y a quelque temps un programme qui établit une connexion avec un serveur Telnet, envoie des chaînes de caractères et analyse la sortie. Le langage de script est simple, mais il fonctionne très bien pour des tâches basiques. Vous trouverez le code source, accompagné d'exemples plus complets, ici
Le script consiste essentiellement en une chaîne d'envoi suivie d'une chaîne d'attente. Le script passe à la ligne suivante dès qu'il détecte la chaîne d'attente ; comme je l'ai dit, c'est très simple. Le script comporte des arguments ; dans la figure 4, j'utilise arg0 pour le mot de passe afin que celui-ci ne soit pas stocké dans le script. L'exécution du script est illustrée à la figure 5. J'ai tronqué la sortie de chaque commande pour gagner de la place. Vous remarquerez que les caractères non de contrôle des chaînes de positionnement de caractères s'affichent jusqu'à ce que je définisse le type de terminal sur ascii.
//login
/login nd/Password?
/arg0/ready
/set_terminal_parameters -terminal_type ascii -pause_lines 0/ready
/foo.cm/ready
/quit/quit
|
|
Figure 4 – Script « send_cmds » permettant de se connecter et d'exécuter la macro de commande « foo » |
send_cmds -IPAddress 192.168.77.128 -InputFilePath test.send_cmds -no_Verbose -a
+rg0 password
SYSTÈME DE TEST PHOENIX CAC VOS (%phx_vos#m16)
*** Pour démarrer sur une autre version de VOS, voir ***
*** >Overseer>COMMON>cfg>reconfig_instructions ***
OpenVOS version 17.1.0ax, module %phx_vos#m16
Veuillez vous connecter 08:15:01
login nd
Mot de passe ?
Noah_Davids.CAC s'est connecté sur %phx_vos#m16 le 21/04/2013 à 08:15:01 (heure normale des Rocheuses).
[f[J[?7l[20l=[1m[1;24r[f[J[J[24;80f
[0;1mPrêt 08:15:01
[0mset_terminal_parameters -terminal_type ascii -pause_lines 0
[1mset_terminal_parameters -terminal_type ascii -pause_lines 0
prêt 08:15:01
foo.cm
display_system_usage
Statistiques d'utilisation pour le module %phx_vos#m16, G94330, OpenVOS version 17.1.0ax
762,6 heures (31,7 jours) de fonctionnement total.
----CPU----- Dernière minute 5 dernières minutes Dernière heure Temps de fonctionnement total
. . . . .
Temps interne 0,00 0,1 % 0,02 0,1 % 0,23 0,1 % 191,65 0,1 %
netstat -statistics
tcp:
. . . .
201766 tcpOutRsts
analyze_system -request_line stcp_meters -all -long -quit
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Le processus actuel est 884, ptep 8D3E6000, Noah_Davids.CAC
stcp_meters %phx_vos#m16 762:36:19 21/04/13 08:15:02
. . . .
bufdat exécuté 678 (moyenne 0,0002/sec)
prêt 08:15:02
prêt 08:15:03
|
|
Figure 5 – Exécution de send_cmds |
s'attendre à :
La bibliothèque gnu_library contient un programme appelé expect. La syntaxe d'un script expect peut être très complexe ; elle permet d'effectuer des branchements en fonction de différentes chaînes de retour, ce qui vous permet de gérer les erreurs de manière intelligente au lieu de simplement attendre l'expiration du délai. Vous pouvez trouver des exemples sur Internet ; il suffit de rechercher « exemples de scripts expect ». Je vais vous présenter un script simple qui se contente de se connecter et d'exécuter la macro foo.cm. Notez qu'il y avait quelques bogues dans les premières versions de gnu_tools (c'est pourquoi j'ai écrit send_cmds), mais à partir de la version 3.4.0a, tout devrait fonctionner correctement. Bien que je ne le montre pas ici, expect peut également utiliser des arguments ; le mot de passe n'a donc pas besoin de faire partie du script, ou bien le script peut vous demander de le saisir. Une fois encore, j'ai tronqué la sortie de la commande du script et vous pouvez voir que les caractères non de contrôle des chaînes de positionnement de caractères s'affichent jusqu'à ce que je définisse le type de terminal sur ascii. Expect filtre toutefois la chaîne différemment, de sorte que tous les caractères ne sont pas affichés.
lancer "telnet"
attendre "telnet>"
envoyer "open 192.168.77.128r"
attendre "login"
envoyer "login ndr"
attendre "Password"
envoyer "passwordr"
attendre "ready"
envoyer "set_terminal_parameters -terminal_type ascii -pause_lines 0r"
attendre "ready"
envoyer "foo.cmr"
attendre "ready"
|
|
Figure 6 – Le script « expect » doit se connecter et exécuter la macro de commande « foo » |
>bin>expect test.expect\
spawn telnet\
telnet> open 192.168.77.128\
Essai en cours...\
Connecté à 192.168.77.128.\
Le caractère d'échappement est « ^] ».
SYSTÈME DE TEST PHOENIX CAC VOS (%phx_vos#m16)
*** Pour démarrer sur une autre version de VOS, voir ***
*** >Overseer>COMMON>cfg>reconfig_instructions ***
OpenVOS version 17.1.0ax, module %phx_vos#m16
Veuillez vous connecter 08:51:28
login nd
Mot de passe ?
Noah_Davids.CAC s'est connecté sur %phx_vos#m16 le 21/04/13 à 08:51:28 mst.
fJ?7l20l
0;1mPrêt 08:51:28
1mset_terminal_parameters -terminal_type ascii -pause_lines 0
prêt 08:51:28
foo.cm
display_system_usage
Statistiques d'utilisation pour le module %phx_vos#m16, G94330, OpenVOS version 17.1.0ax
763,2 heures (31,8 jours) de fonctionnement.
----CPU----- Dernière minute 5 dernières minutes Dernière heure Temps de fonctionnement total
. . . .
Temps interne 0,00 0,1 % 0,02 0,1 % 0,24 0,1 % 191,80 0,1 %
netstat -statistics
tcp:
. . . .
201926 tcpOutRsts
analyze_system -request_line stcp_meters -all -long -quit
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Le processus actuel est 895, ptep 8D2E1200, Noah_Davids.CAC
stcp_meters %phx_vos#m16 763:12:46 21/04/13 08:51:29
. . . .
bufdat exécuté 678 (moyenne 0,0002/sec)
prêt 08:51:29
prêt 08:51:29
|
|
Figure 7 – Exécution du script « expect » |
SSH :
Enfin, vous pouvez utiliser SSH pour exécuter une commande sur un système distant. Si vous avez également configuré l'authentification par clé publique, aucun mot de passe ne vous sera demandé au moment de l'exécution.
L'utilisation de SSH comporte quelques subtilités intéressantes. Tout d'abord, les abréviations ne fonctionnent pas : n'essayez pas d'exécuter « dps », mais utilisez plutôt « display_print_status ».
ssh [email protected] dbs
sh : dbs : commande introuvable
prêt 12:26:25
|
|
Figure 8 – L'utilisation de SSH pour exécuter à distance une commande abrégée ne fonctionne pas |
ssh [email protected] display_batch_status
Files d'attente de traitement par lots pour %phx_vos#m16
FILE ÉTAT MAX TÂCHES EN COURS D'EXÉCUTION
normal en cours 5
prête 12:26:43
|
|
Figure 9 – L'exécution à distance d'une commande via SSH fonctionne |
Deuxièmement, l'exécution directe d'une macro de commande ne fonctionne pas ; notez qu'il n'y a pas de sortie et qu'il semble que seule la première commande de la macro ait été traitée.
ssh [email protected] 'foo.cm'
affichage_de_l'utilisation_du_système
prêt 12:08:40
|
|
Figure 10 – L'utilisation de SSH pour exécuter à distance une macro de commande ne fonctionne pas toujours |
Vous devez plutôt exécuter la commande shell et lui fournir la macro de commande en argument.
ssh [email protected] '/bin/sh foo.cm'
display_system_usage
Statistiques d'utilisation pour le module %phx_vos#m16, G94330, OpenVOS version 17.1.0ax
Total : 766,5 heures (31,9 jours) de fonctionnement.
----CPU----- Dernière minute 5 dernières minutes Dernière heure Temps de fonctionnement total
Minutes CPU 0,02 0,5 % 0,09 0,4 % 0,91 0,4 % 724,76 0,4 %
. . . .
Temps interne 0,00 0,1 % 0,02 0,1 % 0,23 0,1 % 192,57 0,1 %
netstat -statistics
tcp:
. . . .
202796 tcpOutRsts
analyze_system -request_line stcp_meters -all -long -quit
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Processus actuel : 922, ptep 8D3C2780, Noah_Davids.CAC
stcp_meters %phx_vos#m16 766:30:14 21/04/13 12:08:57
. . .
bufdat exécuté 678 (moyenne 0,0002/sec)
prêt 12:08:59
|
|
Figure 11 – Utilisation de SSH pour exécuter à distance une macro de commande en la lançant sous forme de script shell |
Les macros complexes ne fonctionneront pas. Par exemple, chaque ligne de la macro de commande est exécutée dans un processus distinct ; par conséquent, les macros qui utilisent la variable `process_dir` pour stocker des résultats intermédiaires ne fonctionneront pas. Notez que chaque appel à `analyze_system` renvoie un numéro de processus différent.
ssh [email protected] '/bin/sh foo3.cm'
%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm 21/04/13 12:52:20 mst
display foo3.cm
display_line
analyze_system -request_line '' -quit
analyze_system -request_line '' -quit
analyze_system -request_line '' -quit
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Le processus actuel est 1028, ptep 8D3C3000, Noah_Davids.CAC
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Le processus actuel est 1029, ptep 8D3C3000, Noah_Davids.CAC
OpenVOS version 17.1.0ax, analyze_system version 17.1.0ax
Le processus actuel est 1030, ptep 8D3C3000, Noah_Davids.CAC
prêt 12:52:21
|
|
Figure 12 – Chaque commande de la macro est exécutée dans un processus distinct |
L'utilisation de macros de commande avec des variables de type VOS génère des erreurs de syntaxe, car le shell ne les reconnaît pas. La macro de commande foo3.cm s'affiche, puis compte jusqu'à 9. La commande display est exécutée et « &set » génère une erreur de syntaxe.
ssh [email protected] '/bin/sh foo3.cm'
%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm 13-04-22 07:33:18 mst
display foo3.cm
&set COUNT 1
&label again
display_line &COUNT&
&set COUNT (calc &COUNT& + 1)
&if &COUNT& < 10 &then &goto again
foo3.cm: line 2: syntax error near unexpected token `&s'
foo3.cm: line 2: `&set COUNT 1'
ready 07:33:18
|
|
Figure 13 – Les macros de commande utilisant des variables de type VOS ne fonctionneront pas |
Mais l'utilisation de variables de shell fonctionnera. Cela peut bien sûr nécessiter une refonte importante des macros existantes. Voici un exemple de cette même macro sous forme de script shell.
ssh [email protected] '/bin/sh foo3u'
cat foo3u
count=1
while [[ $count -le 9 ]]
do
echo "$count"
(( count++ ))
done
1
2
3
4
5
6
7
8
9
prêt 07:44:41
|
|
Figure 14 – Le script Shell utilisant des variables de type shell fonctionne |
Cependant, vous pouvez exécuter votre macro de commande de type VOS en tant que processus lancé, puis afficher le fichier de sortie ainsi généré. La macro start_foo3.cm exécute start_process, attend que le processus se termine, puis affiche le fichier de sortie sans en-tête. J'ai modifié le fichier foo3.cm afin de désactiver les lignes de commande et de macro, ainsi que l'invite « ready », afin de reproduire plus fidèlement la sortie d'une macro de commande exécutée en mode interactif.
start_process foo3.cm -wait
display foo3.out -no_header
|
|
Figure 15 – Macro de commande permettant d'exécuter foo3.cm en tant que processus démarré |
À l'exception de l'en-tête de connexion, du nom de la macro de commande sur les deux premières lignes et de la ligne « Process finished » à la fin, les résultats sont identiques à ceux obtenus si vous aviez exécuté la macro à partir de la ligne de commande VOS.
ssh [email protected] '/bin/sh start_foo3.cm'
Noah_Davids.CAC logged in on %phx_vos#m16 at 13-04-22 10:45:23 mst.
foo3.cm
%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm 13-04-22 10:45:23 mst
&echo no_input_lines no_command_lines no_macro_lines
set_ready -format off
display foo3.cm
&set COUNT 1
&label again
display_line &COUNT&
&set COUNT (calc &COUNT& + 1)
&if &COUNT& < 10 &then &goto again
1
2
3
4
5
6
7
8
9
Process finished.
ready 10:45:25
|
|
Figure 16 – Résultats de l'exécution de foo.cm dans un processus lancé |
Comme vous pouvez le constater, même si vous ne pouvez pas utiliser Telnet, il existe d'autres moyens de se connecter automatiquement et d'exécuter des commandes.
