No sistema de agendamento de tarefas, o cron, existe a possibilidade de controle de acesso pelos arquivos /etc/cron.allow/etc/cron.deny.  Existindo somente o /etc/cron.allow no sistema, o usuário deverá ter seu login incluso nesse arquivo para fazer uso do cron.  Do contrário será brindando com uma mensagem semelhante a essa:

You (helio) are not allowed to use this program (crontab)
See crontab(1) for more information

Nos ambientes de telecomunicações, onde muitos dos sistemas operacionais em uso são Solaris, ex-Sun e agora da Oracle, esses vêm com essa forma de controle do cron habilitada por padrão.

Isso aumenta a segurança do sistema, mas também torna alguns trabalhos simples mais difíceis, principalmente quando é necessário ter agendamento de trabalho.  Claro que isso poderia ser resolvido com ajuda de um bom administrador de sistemas, o sysadmin, e conhecimento em Unix, mas isso parece estar se tornando cada vez mais raro nesses dias.

Então criei o mycrond, um daemon escrito em perl, para rodar periodicamente como o crond do sistema.  A sintaxe não é perfeita e tem alguns furos, como não aceitar "*/5" para tarefas a cada 5 intervalos, mas utiliza uma sintaxe que somente Solaris aceita como, por exemplo para tarefas agendadas para cada 5 minutos, utilizar "0,5,10,15,20,25,30,35,40,45,50,55".  O restante é parecido com o uso normal da crontab.

Não é 100% perfeito, pois acabei deixando a análise de sintaxe incompleta para todos os valores de data, mas funciona perfeitamente como daemon, não morrendo ao sair do sistema, e é capaz de analisar e rodar formas mais simples da crontab.

O conteúdo do programa é o seguinte:


#! /usr/bin/perl
# $Id: mycrond 29 2011-06-22 20:42:35Z helio $
# Date: Wed Jun 22 12:37:00 BRT 2011
# Author: Helio Loureiro
# Description: an user level alternative to system crond.
#


my $ROOTDIR = "/home/helio/AUDIT";

exit(0); # Edit $ROOTDIR settings and comment this exit.

my $CRONFILE = $ROOTDIR."/etc/crontab";
my $PIDFILE = $ROOTDIR."/var/run/mycrond.pid";

$SIG{CHLD} = 'IGNORE'; #avoid zombies, or they can eat your brain

### Starting in daemon mode
&Daemonize();


sub CheckDir() {
	my $dir = $_[0];
	if ( ! -d "$dir" ) {
		system("mkdir -p $dir");
	}
}

sub ParseCronLine() {
	my $cron = $_[0];
	chomp($cron);

my @params = split(/ /, $cron); my $r_minute = $params[0]; my $r_hour = $params[1]; my $r_day = $params[2]; my $r_month = $params[3]; my $r_dow = $params[4]; my $command = $params[5]; for (my $x = 6; $x < @params; $x++) { $command .= " ".$params[$x]; } my ($second, $minute, $hour, $dayOfMonth, $month, $year, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); $year += 1900; $month++; ### Day of week requires some more work if ($r_dow != '*') { if ($r_dow != $dayOfWeek) { return 0; } } if ($r_month != '*') { $run_status = 0; @months = split(/,/, $r_month); foreach $m (@months) { if ($m == $month) { $run_status++ ; } } return if (! $run_status); } if ($r_day != '*') { $run_status = 0; @days = split(/,/, $r_day); foreach $d (@days) { if ($d == $dayOfMonth) { $run_status++ ; } } return if (! $run_status); } if ($r_minute != '*') { $run_status = 0; @minutes = split(/,/, $r_minute); foreach $m (@minutes) { if ($m == $minute) { $run_status++ ; } } return if (! $run_status); } if ($r_hour != '*') { $run_status = 0; @hours = split(/,/, $r_hour); foreach $h (@hours) { if ($h == $hour) { $run_status++ ; } } return if (! $run_status); } # If it is ok, then run your command if (defined($DEBUG)){ print "Running: $command\n"; } exec "$command" or exit(1); exit(0); } sub Run() { ### Saving process PID my $pid = getppid(); $pid++; &CheckDir($ROOTDIR."/var/run"); open(PID, ">$PIDFILE") or die "Impossible to create $PIDFILE: $!\n"; print PID $pid."\n"; close(PID); open(FD, $CRONFILE) or die "Impossible to read crontab: $!\n"; my @cronlines = ; close(FD); my @PIDS; while (1) { foreach my $line (@cronlines) { next if ($line =~ m/^#/); my $runpid = fork(); if ($runpid == 0) { &ParseCronLine($line); exit(0); } if ($runpid > 0) { push(@PIDS, $runpid); } } sleep(60); } } sub Daemonize() { # Change to / chdir("/"); my $pid = fork(); #first fork if ($pid > 0) { #Parent exists exit(0); } if ($pid == 0) { # Son forks again my $pid2 = fork(); if ($pid2 > 0) { exit(0); } if ($pid2 == 0) { &Run(); } } }
We use cookies

We use cookies on our website. Some of them are essential for the operation of the site, while others help us to improve this site and the user experience (tracking cookies). You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.