Difference between revisions of "Packages.xml:Spanish"

From WPKG | Open Source Software Deployment and Distribution
Jump to: navigation, search
(Uninstall)
(Execute)
Line 202: Line 202:
 
===Execute===
 
===Execute===
  
Execute allows you to execute any script which checks if an application is installed. WPKG checks the exit code of the script to determine the existence of the particular software package.
+
Permite ejecutar un script para comprobar si una aplicación está instalada. WPKG comprueba el código de finalización del script para determinar la existencia del paquete.
This type of check also allows very complex checks. For example there is a limitation of the RegRead method used by WPKG's Registry checks to query registry values which contain backslashes '\'. Now you can execute a batch script which checks for such registry values using 'reg query ...'.  
+
 
There are several possible conditions available for execute checks:
+
Este tipo de comprobaciones también permite complejas verificaciones. Por ejemplo hay una limitación en el método de lectura del registro utilizado por WPKG para comprobar valores que contienen el carácter '\'. Ahora puede ejecutar un 'script de tipo batch' que compruebe el valor del registro utilizando 'reg query ...'.  
 +
 
 +
Hay varias posibles condiciones disponibles para conocer los resultados de las comprobaciones:
  
 
<div style="margin-left: 30px">
 
<div style="margin-left: 30px">
'''exitcodesmallerthan''' - This checks the exit code of the executed script. If the exit code is smaller than the supplied value, the condition returns true.
+
'''exitcodesmallerthan''' - Esto comprueba que el código de salida del script ejecutado es inferior al dato proporcionado, en cuyo caso devuelve ''true''.
  
'''exitcodelessorequal''' - This checks the exit code of the executed script. If the exit code is less or equal to the supplied value, the condition returns true.
+
'''exitcodelessorequal''' - idem., con menor o igual...
  
'''exitcodeequalto''' - This checks the exit code of the executed script. If the exit code is equal to the supplied value, the condition returns true.
+
'''exitcodeequalto''' - idme., con igual...
  
'''exitcodegreaterorequal''' - This checks the exit code of the executed script. If the exit code is greater than of equal to the supplied value, the condition returns true.
+
'''exitcodegreaterorequal''' - idem., con mayor o igual...
  
'''exitcodegreaterthan''' - This checks the exit code of the executed script. If the exit code is greater than the supplied value, the condition returns true.
+
'''exitcodegreaterthan''' - idem., con mayor que...
 
</div>
 
</div>
  
Examples:
+
Ejemplos:
  
This evaluates true if the exit code is negative
+
Ésto comprueba que el código de salida sea negativo, en cuyo caso devuelve ''true'':
 
<source lang="xml">
 
<source lang="xml">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodesmallerthan" value="0">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodesmallerthan" value="0">
 
</source>
 
</source>
  
This evalueates true if exit code is 0 or negative
+
Ésto será cierto si el código de salida es 0 o negativo:
 
<source lang="xml">
 
<source lang="xml">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodelessorequal" value="0" >
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodelessorequal" value="0" >
 
</source>
 
</source>
  
This evaluates true only if exit code is exactly 0  
+
Ésto sólo es cierto cuando el código de salida sea exactamete 0:
 
<source lang="xml">
 
<source lang="xml">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodeequalto" value="0" >
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodeequalto" value="0" >
 
</source>
 
</source>
  
This evaluates true if exit code is 0 or any positive number
+
Ésto será cierto si el código de salida es 0 o cualquier número positivo:
 
<source lang="xml">
 
<source lang="xml">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterorequal" value="0" >
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterorequal" value="0" >
 
</source>
 
</source>
  
This evaluates true if exit code is any positive number
+
Ésto sólo será cierto cuando el código de salida sea positivo:
 
<source lang="xml">
 
<source lang="xml">
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterthan" value="0" >
 
<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterthan" value="0" >

Revision as of 11:08, 19 October 2010

Este documento en otros idiomas: Inglés Francés


packages.xml es el fichero que indica como realizar las instalaciones, actualizaciones y desinstalaciones de los paquetes de software. En otras palabras, es la lista de todos los programas y scripts que pueden ser instalados o ejecutados en las estaciones de trabajo.

Este fichero se localiza en el mismo directorio que wpkg.js.

WPKG no trabajará sin este fichero.

Estructura de packages.xml

La estructura básica de packages.xml es la siguiente:

<packages>
<package
id="wpkg1"
name="Windows Packager sample 1"
revision="1"
reboot="false"
priority="0">
<check type="registry" condition="exists" path="HKLM\Software\wpkg\full\key\not\part\of\it" />
<check type="file" condition="exists" path="%PROGRAMFILES%\wpkg\wpkg.bat" />
<check type="uninstall" condition="exists" path="WPKG" />

<install cmd='msiexec /i (path to msi)'>
<exit code="0" />
</install>

<remove  cmd='%PROGRAMFILES%\uninstall\uninst.exe -quiet' />

<upgrade cmd='msiexec /i (path to msi)' />

</package>

</packages>

Cada paquete tiene los siguientes atributos:

  • id - un identificador único que representa al paquete. Debería ser corto y representativo.
  • name - descripción de texto del paquete. Esto debería ser el nombre completo del producto.
  • revision - un número de versión creado por el usuario que representa la "versión" específica del "WPKG package" para esta instalación. Si cambias el paquete ".XML", incrementalo. Puede ser la revisión del paquete para WPKG, o la versión del programa de software (aunque tenga en cuenta que esta estrategia no evitará que tenga que cambiar el número de versión, cada vez que modifique el fichero de paquete, por ejemplo cuando realize una mejora o corrija un bug en este fichero XML, y la aplicación de software ya esté actualizada).
    • Los siguientes formatos son soportados:
      • un entero (1, 10, 1000, etc.)
      • números de versión separados por puntos (1.1, 2.1.4, 3.200.3987, etc.) ... introducidos en WPKG 1.0
      • revisiones volátiles (1.2RC1, 1.5I32, 2.73M24, 1.65.b, etc.) ... introducidas en WPKG 1.1.1 (mirar el changelog para más ejemplos)
    • Si le gusta hacer un seguimiento de fechas de los últimos cambios realizados en el paquete, en lugar del número de revisión, puede utilizar el formato YYYY.MM.DD (2010.07.27, etc.)
    • Además puede definir una variable dentro del paquete y utilizarla como revisión, lo que puede ser útil si se utiliza en diferentes lugares del paquete (revisión del paquete, camino para instalar, comprobaciones.) ... introducidos en WPKG 1.1.2:
<package 
  id="firefox"
  name="Mozilla Firefox"
  revision="%PKG_VERSION%"
  reboot="false"
  priority="10">

  <variable name="PKG_VERSION" value="3.6.8" />
  • reboot - indica si el sistema debe "rebotar" tras realizar con éxito la instalación, desinstalación o actualización de un paquete.
    • true - siempre reiniciar después de procesar satisfactoriamente el paquete.
    • postponed - reiniciar después de que WPKG halla terminado de procesar todos los paquetes, si los controles del paquete tienen éxito después de la acción.
    • cualquier otra cosa - no causa el reinicio debidoa este paquete. Otros paquetes todavía sí pueden forzar la reiniciación.
  • priority - especifica un valor numérico que determina en que orden el paquete será instalado. Los números mayores, la mayor prioridad, y por eso, el primer paquete que se instalará será el que tenga la mayor prioridad. Por ejemplo:
    • 2 - instala este paquete el primero
    • 1 - instala este paquete el segundo
    • 0 - instala este paquete el tercero

Note que la instalación de un paquete con la prioridad de '5' se instará antes que cualquiera de estos.

Comprobar condiciones / typos de comprobaciones

Por supuesto, no sería prudente lanzar el instalador de una aplicación que ya está instalada. Por eso tiene sentido, "comprobar las condiciones".

Las condiciones de verificación, también se utilizan después de que la instalación haya finlizado para verificar que el software se ha comportado de forma satisfactoria.

Si no existen sentencias de comprobación en el paquete, WPKG actuará ejecutando los comandos de instalación (o actualización) y (si no se detectan errores) añadirá/actualizará los detalles del paquete en la base de datos local del cliente.

Las condiciones de comprobación se pueden dividir en 4 categorías:

  • Registry - Comprueba condiciones del registro de Windows
  • File - Verifica diferentes informaciones sobre los archivos y el sistema de archivos
  • Uninstall - Comprueba información de instalación en el registro de Windows (que Windows utiliza en la lista de agregar/quitar programas)
  • Execute - Ejecuta un script y comprueba el valor de "errorlevel" devuelto por la ejecución (desde la versión WPKG 1.1.0)
  • Logical también puede ser utilizado.

Registry

Registry permite comprobar la existencia de una clave del registro con un determinado valor (Nota: en pre-1.0 versions, sólo trabaja comprobando un valor del registro, no la existencia de una clave).


Cuidado, hay una limitación en el método de lectura de valores del registro que utiliza WPKG para buscar las claves que contienen el caracter ('\'). Vea la sección de ejecución más abajo para abordar esta cuestión.

Hay dos posibles condiciones disponibles para las comprobaciones del registro: exists y equals.

exists - Esto comprueba la existencia de una clave del registro. Si se encuentra la clave, la condición devuelve true, en caso contrario devuelveeee false. equals - Comprueba un valor específico de una clave del registro. Si se encuentra la clave y el valor es igual al proporcionado, la condición devuelve true, en caso contrario false.

Ejemplos:

Esto comprueba la existencia de Adobe Reader dentro del registro:

<check type="registry" condition="exists" path="HKLM\Software\Adobe\Adobe Reader\7.0" />

Esto comprueba si la versión instalada de Firefox es la de idioma US English, con número de versión 1.5.0.6:

<check type="registry" condition="equals" path="HKLM\Software\Mozilla\Mozilla Firefox\CurrentVersion" value="1.5.0.6 (en-US)" />


File

Para comprobar la existencia de un fichero, su tamaño en concreto, o la información de versión del archivo. Hay varias posibles condiciones disponibles para las comprobaciones:

exists - Esto comprueba la existencia de un fichero. Si el fichero existe, la condición devuelve true.

sizeequals - Esto comprueba el tamaño de un fichero. Si se encuentra el archivo y su tamaño es el mismo que el suministrado en la condición, devuelve true.

versionsmallerthan - Comprueba la versión de un fichero en particular. Si se encuentra el archivo y su versión es inferior al número de versión suministrado, la condición devuelve true.

versionlessorequal - Comprueba la versión de un fichero en particular. Si el fichero se encuentra y la versión es inferior o igual a la suministrada en la condición, devuelve true.

versionequalto - Comprueba la versión de un fichero en particular. Si se encuentra el fichero y su versión es igual a la proporcionada en la condición devuelve true.

versiongreaterorequal - Comprueba la versión de un fichero en particular. Si se encuentra el fichero y su versión es mayor o igual a la proporcionada en la condición devuelve true.

versiongreaterthan - Comprueba la versión de un fichero en particular. Si se encuentra el fichero y su versión es mayor que la proporcionada en la condición devuelve true.

Ejemplos:

Esto comprueba si existe Adobe Reader dentro del sistema de archivos:

<check type="file" condition="exists" path="%PROGRAMFILES%\Adobe\Acrobat 7.0\Reader\AcroRd32.exe" />

Esto comprueba si la versión si está instalada la el Firefox US English version 1.5.0.6 comprobando la coincidencia del tamaño de su fichero ejecutable:

<check type="file" condition="sizeequals" path="%PROGRAMFILES%\Mozilla Firefox\firefox.exe" value="7183469" />

Coprueba si la versión del ejecutable de Firefox (.exe) que está instalado es inferior a la 1.5.0.6:

<check type="file" condition="versionsmallerthan" path="%PROGRAMFILES%\Mozilla Firefox\firefox.exe" value="1.5.0.6" />


Uninstall

La desinstalación le permite comprobar la instalación de software según las claves de registro de Microsoft (visualizado por Windows en la sección de agregar o quitar programas), y asi comprobar si se ha instalado una aplicación particular. Microsoft mantiene la lista de aplicaciones instaladas y disponibles para desinstalar en la clave de registro HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall. El valor de DisplayName de una entrada en particular es lo que se pretende encontrar. Versiones pre-1.1.de WPKG disponen sólo de la condición de comprobar si esta opción exists.

exists - Esto comprueba la existencia de un paquete de software en particular en la base de datos de instalaciones. Si el paquete se encuentra, la condición devuelve true.

Desde la versión 1.1.0 la comprobación se extiende con otras condiciones:

versionsmallerthan - Esto comprueba la existencia de un paquete en particular in la base de datos de instalaciones y también comprueba la versión de ese software. Si se encuentra el pquete y la versión es más pequeña que el valor proporcionado, la condición devuelve true.

versionlessorequal - idem., con menor o igual...

versionequalto - idem., con igual...

versiongreaterorequal - idem., con mayor o igual...

versiongreaterthan - idem., con mayor que...

Ejemplos:

Esto comprueba que está instalado Adobe Reader através de la lista de instalaciones:

<check type="uninstall" condition="exists" path="Adobe Reader 7.0" />

Esto comprueba si la versión de Firefox, 1.5.0.6 está instalada en la lista de instalaciones:

<check type="uninstall" condition="exists" path="Mozilla Firefox (1.5.0.6)" />

Esto compruba la existencia de la aplicación Gimp 2.6.6 o superior en la lista de programas instalados:

<check type="uninstall" condition="versiongreaterorequal" path="GIMP" value="2.6.6" />

Execute

Permite ejecutar un script para comprobar si una aplicación está instalada. WPKG comprueba el código de finalización del script para determinar la existencia del paquete.

Este tipo de comprobaciones también permite complejas verificaciones. Por ejemplo hay una limitación en el método de lectura del registro utilizado por WPKG para comprobar valores que contienen el carácter '\'. Ahora puede ejecutar un 'script de tipo batch' que compruebe el valor del registro utilizando 'reg query ...'.

Hay varias posibles condiciones disponibles para conocer los resultados de las comprobaciones:

exitcodesmallerthan - Esto comprueba que el código de salida del script ejecutado es inferior al dato proporcionado, en cuyo caso devuelve true.

exitcodelessorequal - idem., con menor o igual...

exitcodeequalto - idme., con igual...

exitcodegreaterorequal - idem., con mayor o igual...

exitcodegreaterthan - idem., con mayor que...

Ejemplos:

Ésto comprueba que el código de salida sea negativo, en cuyo caso devuelve true:

<check type="execute" path="\\path\to\script.cmd" condition="exitcodesmallerthan" value="0">

Ésto será cierto si el código de salida es 0 o negativo:

<check type="execute" path="\\path\to\script.cmd" condition="exitcodelessorequal" value="0" >

Ésto sólo es cierto cuando el código de salida sea exactamete 0:

<check type="execute" path="\\path\to\script.cmd" condition="exitcodeequalto" value="0" >

Ésto será cierto si el código de salida es 0 o cualquier número positivo:

<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterorequal" value="0" >

Ésto sólo será cierto cuando el código de salida sea positivo:

<check type="execute" path="\\path\to\script.cmd" condition="exitcodegreaterthan" value="0" >

Logical Conditions

There can be zero or more conditions verified during the existence checks. If no conditions are supplied, WPKG attempts to install the package regardless of whether it's currently installed or not. To facilitate using more than one condition, there is a 4th type of condition that can be added, called the logical condition. Logical conditions allow you to create multiple conditions while checking for the presence of an existing package. Logical conditions are top level conditions, with the real check conditions as subnodes in the XML.

The following logical conditions are available: not, and, or, atleast, and atmost.

  • ) both atleast and atmost do require the parameter value=

Examples:

Let's say, for the sake of argument, that you have an Adobe Reader 7.0.8 package that you want installed, but you only want it installed on workstations that are running Windows XP Service Pack 2 or higher, due to some strange incompatibility. Let's also say that some workstations can't be upgraded to Windows XP Service Pack 2 until those workstations are upgraded from 256MB of memory to 512MB of memory. For a scenario like this, you could (and probably should!) use multiple profiles and have those SP1 workstations in one profile, while the SP2 workstations are in another. However, just for example purposes, let's say all workstations are in a single profile. You can provide a logical condition in order for only those workstations running SP2 to be upgraded to Adobe Reader 7.0.8:

<check type="logical" condition="or">
   <check type="registry" condition="exists" path="HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Acrobat Reader\7.0\Installer\Updates\708" />
   <check type="registry" condition="equals" path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CSDVersion" value="Service Pack 1" />
</check>

The 2nd condition here might seem counter intuitive, but remember that you're looking for the absence of things rather than the existence of things when you're writing check conditions. What the above condition says is "Is Adobe Reader 7.0.8 installed or is Service Pack 1 installed? If either of these conditions equates to true, the installation will be skipped. In this particular case, Adobe Reader 7.0.8 isn't installed, but the value of CSDVersion is Service Pack 1 (for the SP1 boxes) so the software will not be installed.

Once all conditions have been tested, if the final result of the conditions is equal to false, WPKG will try to execute the "install cmd".


After it's executed, WPKG will check the exit code (should be 0 in this example) *and* verify all the checks.


If *any* of the checks are not met, software is considered *not* installed - so enter these values carefully!


Also, if no checks were specified, WPKG will say that the installation have failed. Although this is useful for cases where you want to install the package every time WPKG runs, you will probably want the installation without an error - see Execute once / always for executing packages without any checks.


Remember that you don't have to specify all three check conditions, usually one is enough: if the software you are about to install will show up in Windows' Add/Remove Programs (and not all do), it is sufficient to specify just the "uninstall" check.

Actions

WPKG understands several actions: install, upgrade, downgrade, remove and download. Multiple commands for each of these actions can be listed in the config file and WPKG will execute them in the order they are listed.

The install commands are executed by WPKG when a new package comes into scope for a profile.

The upgrade commands are executed when a new revision of a package comes into scope. That is, when the revision number in the packages.xml file on the server is larger than the one in the local wpkg.xml file. Note that the upgrade commands will be run even if the check conditions are already met.

The downgrade commands are executed if the version installed on the client is newer than the one on the server side.

The remove commands are executed when a package is removed from a profile.

The download commands are always executed when used on the global package level. Since WPKG version 1.1.0 however, this command is also allowed as a sub-node of any of the other commands. This allows you to specify a download which is only downloaded for a specific command. This was implemented since it usually makes no sense to download the installation package again right before the remove commands are executed (which usually runs a local uninstall command which does not need the original installer). Note: If multiple install (or upgrade/downgrade/remove) commands are specified WPKG will download the the files of all command nodes of the same kind before starting to execute the commands in sequence.

In many of the examples in the Category:Silent_Installers section, cmd.exe is executed to perform environment variable expansion and to use 'start /wait' to wait on the command being executed. This method of executing commands results in cmd windows appearing on screen. However, this method does not appear to be necessary. The current version of WPKG executes commands using the WScript.Shell.Exec() function and expands environment variables before execution. WPKG then waits until the command is completed before continuing.

The correct method of executing a command interpreter is to use the %comspec% environment variable, not specifying cmd.exe explicitly. This is needed to run commands that are built into the interpreter and are not separate executables.

When the output of a command (think of: copy,cacls) is too much, the command will fail. You have to redirect the output to NUL or a file (example: "%command% >nul").

Typical examples:

<download url='http://wpkg.example.com/installers/some.msi' target="installers\some.msi" />
<install cmd="msiexec /qn /i %SOFTWARE%\package.msi" />
<install cmd="msiexec /qn /i %SOFTWARE%\package.msi" timeout="1800" />
<install cmd="%comspec% /c copy %SOFTWARE%\file.dll %WINDIR%" />
<remove cmd="msiexec /qn /x %SOFTWARE%\package.msi" />

The timeout option (Timeouts) tells WPKG how long to wait for the command to complete. It is in seconds and the default is 3600 seconds.

If the command you specify returns a value of "0" then wpkg assumes it was successful and continues with the next command, if any. If the command returns a nonzero value, then wpkg stops and logs a failure for the package. Sometimes nonzero exit codes are expected and you want to accept them. You can do this by adding exit code sections inside the install section, like this:

<install cmd="msiexec /qn /i %SOFTWARE%\package.msi" >
    <exit code="0" />
    <exit code="259" />
</install>

If you don't care about exit code, use exit code="any":

<install cmd="msiexec /qn /i %SOFTWARE%\installer.exe /silent" >
    <exit code="any" />
</install>


You can set a specific reboot action for certain exit codes with something like the following:

<install cmd="msiexec /qn /i %SOFTWARE%\package.msi" >
    <exit code="3010" reboot="true" />
    <exit code="0" />
</install>

The options for the exit code reboot are:

  • true - immediate reboot, without updating wpkg.xml
  • delayed - reboot once the package action is complete and wpkg.xml is updated
  • postponed - reboot once all the packages have been processed

Please note that the target value for a download action is always relative to the downloadDir defined in wpkg.js (and there's currently no configuration option to change this from the default of %TEMP%).

Ejemplos rápidos

Otro ejemplo - WPKG comprueba si el paquete ha sido ya instalado en la parte de Windows de 'agregar o quitar programas' exclusivamente antes de decidir instalarlo (para asegurarse de que no ha sido instalado previamente):

<package
id="wpkg3"
name="Windows Packager sample 3"
revision="1"
reboot="false"
priority="1">

<!--
This is a comment.
Checks in Windows' Add/Remove Programs only.
-->
<check type="uninstall" condition="exists" path="WPKG" />

<install cmd='%PACKAGES%\package.exe /quiet /install' />

<remove  cmd='%PACKAGES%\package.exe /quiet /uninstall' />

<upgrade cmd='%PACKAGES%\package.exe /quiet /install' />

</package>

En el siguiete no hay condiciones de comprobación. Esto significa que WPKG lo ejecutará cada vez que el equipo arranque e instalará el software:

<package
id="backupfiles"
name="Makes backup of some file"
revision="1"
reboot="false"
priority="0">

<!--
This is a comment.
'''No check conditions; script will be executed *each time* wpkg.js is called - each time PC is booted.'''
-->

<install cmd='\\server\path\script.bat' />
</package>


Ejemplo similar, también sin condiciones. Tenga en cuenta la entrada execute="once" - esto significa que este script sólo será ejecutado una vez. Esto puede ser útil para tareas que sólo han de realizarse una vez, como desfragmentaciones de disco, algunos test, cambiar impresoras, etc.

<package
id="backupfiles"
name="Makes backup of some file"
revision="1"
reboot="false"
execute="once"
priority="0">

<install cmd='\\server\path\script.bat' />
</package>

De forma similar, si desea ejecutar una aplicación o un script siempre - utilice "always" en lugar de "once". Para más información sobre esta funcionalidad vea esto.

Package dependencies

Packages can also depend on other packages, see package dependencies for more info.


Individual XML package files

If you would rather keep your package XML description in separate files, you can of course do that: just create a packages directory where wpkg.js is, and place individual XML files there (i.e., thunderbird.xml, firefox.xml etc.). The syntax is the same as that of packages.xml.

Note, if you decide to keep all your packages in separate XML files, you still need a packages.xml file, which should at least contain an empty entry:

<?xml version="1.0" encoding="UTF-8"?>
<packages>
</packages>


Here is an example of an individual XML file - note that it must contain <packages> at the beginning and </packages> at the end:

<?xml version="1.0" encoding="UTF-8"?>
<packages>
 <package id="setadminpassword"
          name="Set admin password"
          revision="1"
          priority="999"
          reboot="false"
          execute="once">
       <install cmd='cmd /c net user administrator password' />
 </package>
</packages>

WARNING! Please note for this example: The password is visible in the local copy of wpkg.xml, so remove after installation, or better yet, use the command in a separate .bat file.


You can use the following script to convert/merge your individual XML files into one. (I use it for high latency networks). Note: you must run this script from within the packages directory; it ignores badly formed XML documents (and prints a warning); you should remove your packages directory afterwards; it will overwrite your packages.xml file.

#!/bin/bash
echo '<?xml version="1.0" encoding="UTF-8"?>' > ../packages.xml
echo '<packages>' >> ../packages.xml
for package in `ls *.xml`
	do
		xmlwf $package | grep "not well-formed"
		if [ "$?" == "1" ]; then
		   cat $package | sed -e :a -e 's/<\(\(\/\)*packages\)[^>]*>//g;/</N;//ba' | sed -e :a -e 's/<?xml.*>//g;/</N;//ba' >>../packages.xml
		fi
done
echo '</packages>' >> ../packages.xml

Vea también