1 #@ MODIF System Utilitai DATE 29/08/2006 AUTEUR MCOURTOI M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2006 EDF R&D WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
9 # (AT YOUR OPTION) ANY LATER VERSION.
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
18 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
22 """Ce module définit la classe `SYSTEM` et la fonction `ExecCommand`
23 qui est présente uniquement pour commodité pour les Macros.
25 La classe SYSTEM est semblable à celle utilisée dans ASTK_SERV.
28 __all__ = ["SYSTEM", "ExecCommand"]
35 from types import FileType
37 # ----- differ messages translation
41 #-------------------------------------------------------------------------------
42 def _exitcode(status, default=0):
43 """Extrait le code retour du status. Retourne `default` si le process
44 n'a pas fini pas exit.
47 if os.WIFEXITED(status):
48 iret = os.WEXITSTATUS(status)
51 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
53 #-------------------------------------------------------------------------------
55 """Class to encapsultate "system" commands (this a simplified version of
56 ASTER_SYSTEM class defined in ASTK_SERV part).
58 # this value should be set during installation step.
63 #-------------------------------------------------------------------------------
64 def __init__(self, **kargs):
66 Optionnal arguments : silent, verbose, debug, cc_files, maxcmdlen.
68 self.verbose = kargs.get('verbose', True)
69 self.debug = kargs.get('debug', False)
70 self.cc_files = kargs.get('cc_files', None)
71 if kargs.has_key('maxcmdlen'):
72 self.MaxCmdLen = kargs['maxcmdlen']
74 #-------------------------------------------------------------------------------
75 def _mess(self, msg, cod=''):
76 """Just print a message
78 self._print('%-18s %s' % (cod, msg))
80 #-------------------------------------------------------------------------------
81 def _print(self, *args, **kargs):
84 term : line terminator (default to os.linesep).
86 term = kargs.get('term', os.linesep)
87 files = Set([sys.stdout])
89 files.add(self.cc_files)
91 if type(f) is FileType:
92 txt = ' '.join(['%s'%a for a in args])
93 f.write(txt.replace(os.linesep+' ', os.linesep)+term)
96 print _('FileType object expected : %s / %s') % (type(f), repr(f))
98 #-------------------------------------------------------------------------------
99 def VerbStart(self, cmd, verbose=None):
100 """Start message in verbose mode
104 verbose = self.verbose
107 if len(cmd) > Lm-2 or cmd.count('\n') > 0:
108 pcmd = pcmd+'\n'+' '*Lm
109 self._print(('%-'+str(Lm)+'s') % (pcmd,), term='')
111 #-------------------------------------------------------------------------------
112 def VerbEnd(self, iret, output='', verbose=None):
113 """Ends message in verbose mode
116 verbose = self.verbose
119 self._print('[ OK ]')
121 self._print(_('[FAILED]'))
122 self._print(_('Exit code : %d') % iret)
123 if (iret != 0 or self.debug) and output:
126 #-------------------------------------------------------------------------------
127 def VerbIgnore(self, verbose=None):
128 """Ends message in verbose mode
131 verbose = self.verbose
133 self._print(_('[ SKIP ]'))
135 #-------------------------------------------------------------------------------
136 def Shell(self, cmd, bg=False, verbose=None, follow_output=False,
137 alt_comment=None, interact=False):
138 """Execute a command shell
140 bg : put command in background if True
141 verbose : print status messages during execution if True
142 follow_output : follow interactively output of command
143 alt_comment : print this "alternative comment" instead of "cmd"
144 interact : allow the user to interact with the process
145 (don't close stdin). bg=True implies interact=False.
147 iret : exit code if bg = False,
148 process id if bg = True
149 output : output lines (as string)
154 verbose = self.verbose
157 if len(cmd) > self.MaxCmdLen:
158 self._mess((_('length of command shell greater '\
159 'than %d characters.') % self.MaxCmdLen), _('<A>_ALARM'))
161 self._print('<DBG> <local_shell>', cmd)
162 self._print('<DBG> <local_shell> background mode : ', bg)
164 self.VerbStart(alt_comment, verbose=verbose)
165 if follow_output and verbose:
166 self._print(_('\nCommand output :'))
167 # run interactive command
169 iret = os.system(cmd)
170 return _exitcode(iret), ''
171 # use popen to manipulate stdout/stderr
173 p = popen2.Popen4(cmd)
176 if not follow_output:
177 output = p.fromchild.readlines()
179 while p.poll() == -1:
180 output.append(p.fromchild.readline())
182 self._print(output[-1], term='')
183 # to be sure to empty the buffer
184 end = p.fromchild.readlines()
185 self._print(''.join(end))
187 iret = _exitcode(p.wait())
191 output = ''.join(output)
193 # repeat header message
195 self.VerbStart(alt_comment, verbose=verbose)
196 mat = re.search('EXIT_CODE=([0-9]+)', output)
198 iret = int(mat.group(1))
199 self.VerbEnd(iret, output, verbose=verbose)
203 self._print(_('Process ID : '), iret)
206 #-------------------------------------------------------------------------------
207 # Juste par commodité.
209 ExecCommand = system.Shell
212 #-------------------------------------------------------------------------------
213 #-------------------------------------------------------------------------------
214 #-------------------------------------------------------------------------------
215 if __name__ == '__main__':
216 iret, output = ExecCommand('ls', alt_comment='Lancement de la commande...')