'Programas' prácticos en Unix
3 participantes
Página 1 de 1.
'Programas' prácticos en Unix
- Tratamiento de fechas con 'date'
Ejemplos:
~> date
mié mar 17 16:11:30 CET 2010
~> date -d "5 days"
lun mar 22 16:11:43 CET 2010
~> date -d "20040327"
sáb mar 27 00:00:00 CET 2004
~> date -d "20040327 8 days" +"%A, %d de %B de %Y"
domingo, 04 de abril de 2004
~> date -d "20040327 21 days ago" +"%A, %e de %B de %Y"
sábado, 6 de marzo de 2004
Más información:
http://www.linuxtotal.com.mx/index.php?cont=info_admon_007
http://en.wikipedia.org/wiki/Date_(Unix)
Hay 'máquinas Unix' para las que no está habilitada la opción -d de date, por lo que no se pueden aplicar estos ejemplos
- Eliminar un proceso y sus descendientes
Se aplica el siguiente programa con el ID del proceso como argumento
#########################################
#!/bin/ksh
# Mata un proceso y sus descendientes
# El id del proceso se pasa como argumento
# Es una adaptacion de un script de internet:
# http://www.unix.com/unix-dummies-questions-answers/5245-script-kill-all-child-process-given-pid.html
# ------------
# 1 argumento: ppid (es el id del proceso)
ppid=$1
#------------
ppidoriginal=$ppid # Se guarda el id original del proceso para matarlo al final
CURPID=$$ # id de este script; No se quiere matar este script cuando
# sea a su vez un subproceso
if [ -z $ppid ] ; then
echo Hay que dar el PID del proceso como argumento
exit;
fi
arraycounter=1
while true
do
FORLOOP=FALSE
# Captura todos los id de los descendientes
for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'`
do
if [ $i -ne $CURPID ] ; then
procid[$arraycounter]=$i
arraycounter=`expr $arraycounter + 1`
ppid=$i
FORLOOP=TRUE
fi
done
# Se matan primero los hijos y luego los padres
if [ "$FORLOOP" = "FALSE" ] ; then
arraycounter=`expr $arraycounter - 1`
while [ $arraycounter -ne 0 ]
do
kill -9 "${procid[$arraycounter]}" >/dev/null
arraycounter=`expr $arraycounter - 1`
done
kill -9 "$ppidoriginal" # Por ultimo se mata el proceso original
exit
fi
done
exit
#####################################
Ejemplos:
~> date
mié mar 17 16:11:30 CET 2010
~> date -d "5 days"
lun mar 22 16:11:43 CET 2010
~> date -d "20040327"
sáb mar 27 00:00:00 CET 2004
~> date -d "20040327 8 days" +"%A, %d de %B de %Y"
domingo, 04 de abril de 2004
~> date -d "20040327 21 days ago" +"%A, %e de %B de %Y"
sábado, 6 de marzo de 2004
Más información:
http://www.linuxtotal.com.mx/index.php?cont=info_admon_007
http://en.wikipedia.org/wiki/Date_(Unix)
Hay 'máquinas Unix' para las que no está habilitada la opción -d de date, por lo que no se pueden aplicar estos ejemplos
- Eliminar un proceso y sus descendientes
Se aplica el siguiente programa con el ID del proceso como argumento
#########################################
#!/bin/ksh
# Mata un proceso y sus descendientes
# El id del proceso se pasa como argumento
# Es una adaptacion de un script de internet:
# http://www.unix.com/unix-dummies-questions-answers/5245-script-kill-all-child-process-given-pid.html
# ------------
# 1 argumento: ppid (es el id del proceso)
ppid=$1
#------------
ppidoriginal=$ppid # Se guarda el id original del proceso para matarlo al final
CURPID=$$ # id de este script; No se quiere matar este script cuando
# sea a su vez un subproceso
if [ -z $ppid ] ; then
echo Hay que dar el PID del proceso como argumento
exit;
fi
arraycounter=1
while true
do
FORLOOP=FALSE
# Captura todos los id de los descendientes
for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'`
do
if [ $i -ne $CURPID ] ; then
procid[$arraycounter]=$i
arraycounter=`expr $arraycounter + 1`
ppid=$i
FORLOOP=TRUE
fi
done
# Se matan primero los hijos y luego los padres
if [ "$FORLOOP" = "FALSE" ] ; then
arraycounter=`expr $arraycounter - 1`
while [ $arraycounter -ne 0 ]
do
kill -9 "${procid[$arraycounter]}" >/dev/null
arraycounter=`expr $arraycounter - 1`
done
kill -9 "$ppidoriginal" # Por ultimo se mata el proceso original
exit
fi
done
exit
#####################################
Última edición por Alfer el Lun Abr 19, 2010 5:34 pm, editado 4 veces
Alfer- Mensajes : 2
Fecha de inscripción : 01/03/2010
manejo de fechas en UNIX. mandtg
Gracias alfer por tus programas y explicaciones sobre comandos. Sin embargo acabo de comprobar que lo que explicas para date NO es STANDARD. Es válido en algunos casos, pero por ejemplo, no funciona si lo haces en el centro europeo en ecgate, aunque si que funciona en el CRAY.
Para el tema de fechas yo siempre había usado mandtg.c. Quizás muchos de vosotros lo conozcais. Es una utilidad que se escribió para HIRLAM y que funciona muy bien pero solo en formato numerico.
El comando funcionaba así: mandtg YYYYMMDDHH + hh (hacia adelante en el tiempo, hh en horas o mandtg YYYYMMDDHH + -hh (hacia atrás).
Ej. mandtg 2010031812 + 12 --> 2010031900
mandtg 2010031812 + -24 --> 2010031712
Sin embargo, lo que cuentas está muy bien porque obtienes también el día de la semana sin necesidad de calcularlo.
Por si os interesa, el código (en c) está abajo. Sólo teneis que compilarlo (gcc -o mandtg.x mandtg.c) y os funcionará. Resulta muy útil para el manejo de fechas en UNIX. Combinado con cut -c1-4, por ejemplo, extraeremos el año, con cut -c5-6 el mes y así sucesivamente.
ANY=`mandtg 2010031812 + -24|cut -c1-4`
MES=`mandtg 2010031812 + -24|cut -c5-6`
DIA=`mandtg 2010031812 + -24|cut -c7-8`
HORA=`mandtg 2010031812 + -24|cut -c9-10`
FECHA=`mandtg 2010031812 + -24|cut -c1-8`
Como digo, lo que mandtg no te da es el día de la semana, pero para el tema de nombres de ficheros, por ejemplo, suele ser suficiente. El código de mandtg.c son las líneas comprendidas entre COMIENZA CÓDIGO mandtg.c y FIN CÓDIGO mandtg.c (estas dos NO están incluídas)
Un saludo
ACA1969
COMIENZA CÓDIGO mandtg.c
include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
main(argc,argv)
int argc;
char *argv[];
{
long date,year,month,day,hour,min,lag;
if (argc < 4) {
printf("To few arguments %d\n",argc);
exit(0);
}else if (!strchr(argv[2],'+')) {
printf("Only implemented mandtg.x dtg + hh\n");
printf("Exampel: mandtg.x 91010100 + -24\n");
exit(0);
}else if (strlen(argv[1]) < 8 ) {
printf("Argument 1 to short\n");
printf("Exampel: mandtg.x 91010100 + -24\n");
exit(0);
}
date = atol(argv[1]);
lag = 60*(atol(argv[3]));
year = date/1000000;
month = (date - year*1000000)/10000;
day = (date - year*1000000 - month*10000)/100;
hour = (date - year*1000000 - month*10000 - day*100);
min = 0;
NewTime(&year,&month,&day,&hour,&min,lag);
date = year*1000000 + month*10000 + day*100 + hour;
printf("%.8ld\n",date);
exit(0);
}
/*------------------------------------------------------------------------*/
int
NewTime(year,month,day,hour,min,time_incr_min)
int *year,*month,*day,*hour,*min,time_incr_min;
{
static struct tm tid;
static int GMT=0;
int iy;
if (!GMT) {
putenv("TZ=GMT");
GMT=1;
}
iy = *year % 1900;
if (iy < 70 ) iy += 100;
/* let mktime fill in summer time etc */
tid.tm_sec = 10;
tid.tm_min = *min;
tid.tm_hour = *hour;
tid.tm_mday = *day;
tid.tm_mon = *month - 1;
tid.tm_year = iy;
tid.tm_isdst= -1;
mktime(&tid);
/*
put back the date and time (mktime may have change it) and add time lag.
*/
tid.tm_hour = *hour;
tid.tm_mday = *day;
tid.tm_mon = *month - 1;
tid.tm_year = iy;
tid.tm_min = *min + time_incr_min;
tid.tm_isdst= -1;
/* calculate new date and time */
mktime(&tid);
/* return new date */
*min = tid.tm_min;
*hour = tid.tm_hour;
*day = tid.tm_mday;
*month = tid.tm_mon + 1;
if (*year > 1900) {
/* use four digits in year */
*year = tid.tm_year + 1900;
}else{
/* only two digits in year */
*year = tid.tm_year % 100;
}
return 0;
}
FIN CÓDIGO mandtg.c
Para el tema de fechas yo siempre había usado mandtg.c. Quizás muchos de vosotros lo conozcais. Es una utilidad que se escribió para HIRLAM y que funciona muy bien pero solo en formato numerico.
El comando funcionaba así: mandtg YYYYMMDDHH + hh (hacia adelante en el tiempo, hh en horas o mandtg YYYYMMDDHH + -hh (hacia atrás).
Ej. mandtg 2010031812 + 12 --> 2010031900
mandtg 2010031812 + -24 --> 2010031712
Sin embargo, lo que cuentas está muy bien porque obtienes también el día de la semana sin necesidad de calcularlo.
Por si os interesa, el código (en c) está abajo. Sólo teneis que compilarlo (gcc -o mandtg.x mandtg.c) y os funcionará. Resulta muy útil para el manejo de fechas en UNIX. Combinado con cut -c1-4, por ejemplo, extraeremos el año, con cut -c5-6 el mes y así sucesivamente.
ANY=`mandtg 2010031812 + -24|cut -c1-4`
MES=`mandtg 2010031812 + -24|cut -c5-6`
DIA=`mandtg 2010031812 + -24|cut -c7-8`
HORA=`mandtg 2010031812 + -24|cut -c9-10`
FECHA=`mandtg 2010031812 + -24|cut -c1-8`
Como digo, lo que mandtg no te da es el día de la semana, pero para el tema de nombres de ficheros, por ejemplo, suele ser suficiente. El código de mandtg.c son las líneas comprendidas entre COMIENZA CÓDIGO mandtg.c y FIN CÓDIGO mandtg.c (estas dos NO están incluídas)
Un saludo
ACA1969
COMIENZA CÓDIGO mandtg.c
include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
main(argc,argv)
int argc;
char *argv[];
{
long date,year,month,day,hour,min,lag;
if (argc < 4) {
printf("To few arguments %d\n",argc);
exit(0);
}else if (!strchr(argv[2],'+')) {
printf("Only implemented mandtg.x dtg + hh\n");
printf("Exampel: mandtg.x 91010100 + -24\n");
exit(0);
}else if (strlen(argv[1]) < 8 ) {
printf("Argument 1 to short\n");
printf("Exampel: mandtg.x 91010100 + -24\n");
exit(0);
}
date = atol(argv[1]);
lag = 60*(atol(argv[3]));
year = date/1000000;
month = (date - year*1000000)/10000;
day = (date - year*1000000 - month*10000)/100;
hour = (date - year*1000000 - month*10000 - day*100);
min = 0;
NewTime(&year,&month,&day,&hour,&min,lag);
date = year*1000000 + month*10000 + day*100 + hour;
printf("%.8ld\n",date);
exit(0);
}
/*------------------------------------------------------------------------*/
int
NewTime(year,month,day,hour,min,time_incr_min)
int *year,*month,*day,*hour,*min,time_incr_min;
{
static struct tm tid;
static int GMT=0;
int iy;
if (!GMT) {
putenv("TZ=GMT");
GMT=1;
}
iy = *year % 1900;
if (iy < 70 ) iy += 100;
/* let mktime fill in summer time etc */
tid.tm_sec = 10;
tid.tm_min = *min;
tid.tm_hour = *hour;
tid.tm_mday = *day;
tid.tm_mon = *month - 1;
tid.tm_year = iy;
tid.tm_isdst= -1;
mktime(&tid);
/*
put back the date and time (mktime may have change it) and add time lag.
*/
tid.tm_hour = *hour;
tid.tm_mday = *day;
tid.tm_mon = *month - 1;
tid.tm_year = iy;
tid.tm_min = *min + time_incr_min;
tid.tm_isdst= -1;
/* calculate new date and time */
mktime(&tid);
/* return new date */
*min = tid.tm_min;
*hour = tid.tm_hour;
*day = tid.tm_mday;
*month = tid.tm_mon + 1;
if (*year > 1900) {
/* use four digits in year */
*year = tid.tm_year + 1900;
}else{
/* only two digits in year */
*year = tid.tm_year % 100;
}
return 0;
}
FIN CÓDIGO mandtg.c
ACA1969- Mensajes : 3
Fecha de inscripción : 25/02/2010
Re: 'Programas' prácticos en Unix
En el ECMWF se usan las funciones 'datediff' y 'dateincr' para hacer aritmética de fechas:
Usage: datediff [switch] first_date second_date
datediff YYYYMMDD YYYYMMDD
datediff -d YYYYMMDD YYYYMMDD
datediff -h YYYYMMDDhh YYYYMMDDhh
datediff -m YYYYMMDDhhmm YYYYMMDDhhmm
datediff -s YYYYMMDDhhmmss YYYYMMDDhhmmss
Usage: dateincr [switch] basedate increment
dateincr YYYYMMDD [+|-]days
dateincr -d YYYYMMDD [+|-]days
dateincr -h YYYYMMDDhh [+|-]hours
dateincr -m YYYYMMDDhhmm [+|-]minutes
dateincr -s YYYYMMDDhhmmss [+|-]seconds
Usage: datediff [switch] first_date second_date
datediff YYYYMMDD YYYYMMDD
datediff -d YYYYMMDD YYYYMMDD
datediff -h YYYYMMDDhh YYYYMMDDhh
datediff -m YYYYMMDDhhmm YYYYMMDDhhmm
datediff -s YYYYMMDDhhmmss YYYYMMDDhhmmss
Usage: dateincr [switch] basedate increment
dateincr YYYYMMDD [+|-]days
dateincr -d YYYYMMDD [+|-]days
dateincr -h YYYYMMDDhh [+|-]hours
dateincr -m YYYYMMDDhhmm [+|-]minutes
dateincr -s YYYYMMDDhhmmss [+|-]seconds
Ernesto- Mensajes : 11
Fecha de inscripción : 09/03/2010
Página 1 de 1.
Permisos de este foro:
No puedes responder a temas en este foro.
|
|