Linux en Espanol
 
[BASH][Solucionado] Carga variables como literales (tema #24818)
Publicar nuevo tema  Responder al tema    Foros de discusión -> Programación
Autor Mensaje
nordri
Forista
Registrado: 2005-03-25
Mensajes: 12

Publicado: 2013-11-23 10:19:57    Asunto: [BASH][Solucionado] Carga variables como literales

Hola a todos,

Siento el t?tulo tan criptico pero tampoco sab?a bien como resumir este problema en una sola frase.

Os cuento, estoy haciendo un programita para controlar los logs de Apache de una Debian 6.

Para cargar las variables uso el fichero envvars con un
[code:1:eb62909f5f]. /etc/apache2/envvars[/code:1:eb62909f5f]
Y funciona perfectamente al hacer un
[code:1:eb62909f5f]echo ${APACHE_LOG_DIR}[/code:1:eb62909f5f]

Entonces leo el directorio sites-available haciendo los siguiente
[code:1:eb62909f5f]grep CustomLog $APACHE_VHOSTS_DIR/$VHOST | awk -F" " '{ print $2 }' [/code:1:eb62909f5f]
que deber?a devolver una cadena como /var/log/apache2/access.log o similar.

Pero el problema es que la cadena dentro del archivo VHOST est? escrita como ${APACHE_LOG_DIR}/access.log

Entonces cuando trato de leer el fichero con stat para ver el tama?o me dice
[code:1:eb62909f5f]stat: cannot stat `${APACHE_LOG_DIR}/access.log': No such file or directory[/code:1:eb62909f5f]

Ol?! y ahora no s? ni encuentro ninguna informaci?n para poder sustituir la variable por su valor correspondiente. M?s viendo que esa variable es accesible durante la ejecuci?n del script.

Le he dado bastantes vueltas desde meterla en otro archivo y cargarla como si fuera un fichero de configuraci?n pero intenta ejecutarlo en lugar de cargarlo como variable. He intentado pasarlo a otra variable pero se mantiene como cadena. No s? si se os ocurre algo m?s. A continuaci?n os dejo el script completo.

[code:1:eb62909f5f]#!/bin/bash

APACHE_ENVVARS="/etc/apache2/envvars";
APACHE_VHOSTS_DIR="/etc/apache2/sites-available";
let MAX_SIZE=0;

. $APACHE_ENVVARS

echo "Log dir: ${APACHE_LOG_DIR}";

for VHOST in $(ls $APACHE_VHOSTS_DIR);
do
echo $VHOST; # Debug
VHOST_LOG_FILE=$(grep CustomLog $APACHE_VHOSTS_DIR/$VHOST | awk -F" " '{ print $2 }' );
VHOST_LOG_SIZE=$(stat --format "%s" $VHOST_LOG_FILE);
if [[ $VHOST_LOG_SIZE -gt $MAX_SIZE ]]; then
let MAX_SIZE=$VHOST_LOG_SIZE;
fi
done

echo "El log mayor es $MAX_SIZE";
[/code:1:eb62909f5f]

Un saludo y gracias
miguelgf
Forista


Registrado: 2006-12-28
Mensajes: 621

Publicado: 2013-11-23 22:52:21    Asunto:

Hola.

Puedes usar una variable cuyo contenido es el nombre de otra usando "!" as?:
[code:1:4c9d632fb9]SUBORDINADA="Hola"
PRINCIPAL="SUBORDINADA"
echo principal vale $PRINCIPAL
echo subordinada vale $SUBORDINADA
echo y con redirecci?n subordinada vale ${!PRINCIPAL}[/code:1:4c9d632fb9]
Si ejecutas ese ejemplo te saldr?:[code:1:4c9d632fb9]principal vale SUBORDINADA
subordinada vale Hola
y con redirecci?n subordinada vale Hola[/code:1:4c9d632fb9]
Hay que observar que una variable contiene el nombre de la otra sin llaves "{}" ni d?lar "$" ni otros caracteres adicionales.
Una vez sabido esto, lo m?s complicado ser? separar el nombre de la variable del resto de la cadena y reconstruir de nuevo. Tu script podr?a quedar as?:
[code:1:4c9d632fb9]#!/bin/bash

APACHE_ENVVARS="/etc/apache2/envvars";
APACHE_VHOSTS_DIR="/etc/apache2/sites-available";
let MAX_SIZE=0;

. $APACHE_ENVVARS

echo "Log dir: ${APACHE_LOG_DIR}";

for VHOST in $(ls $APACHE_VHOSTS_DIR);
do
echo $VHOST; # Debug
VHOST_LOG_FILE=$(grep CustomLog $APACHE_VHOSTS_DIR/$VHOST | awk -F" " '{ print $2 }' );
#
FICHERO=$(echo $VHOST_LOG_FILE | awk -F '}' '{print $2}')
VARIABLE=$(echo $VHOST_LOG_FILE | awk -F '{|}' '{print $2}')
VHOST_LOG_SIZE=$(stat --format "%s" ${!VARIABLE}$FICHERO)
#
if [[ $VHOST_LOG_SIZE -gt $MAX_SIZE ]]; then
let MAX_SIZE=$VHOST_LOG_SIZE;
fi
done

echo "El log mayor es $MAX_SIZE";[/code:1:4c9d632fb9]

Saludos.
nordri
Forista
Registrado: 2005-03-25
Mensajes: 12

Publicado: 2013-11-24 09:38:45    Asunto:

Perfecto compa?ero!!

Muchis?mas gracias.





La marca registrada Linux (R) se usa siguiendo la sublicensia obtenida del "Linux Mark Institute",
el LICENCIATARIO exclusivo de Linus Torvalds, propietario de la marca en EEUU y otros países
The registered trademark Linux (R) is used pursuant to a sublicense from the Linux Mark Institute,
the exclusive LICENSEE of Linus Torvalds, owner of the mark in the U.S. and other countries