skilled has asked for the wisdom of the Perl Monks concerning the following question:

Hello all, i have problem with the following: I am trying to run script for OTRS (Helpdesk system) but i got window that Perl Command Line is not working. I am using windows server 2012 R2 64bit The details of error:(sorry, some words of german) Problemereignisname: APPCRASH Anwendungsname: perl.exe Anwendungsversion: 5.16.3.1604 Anwendungszeitstempel: 534c5f7a Fehlermodulname: encoding.dll Fehlermodulversion: 0.0.0.0 Fehlermodulzeitstempel: 534c5fe6 Ausnahmecode: c0000005 Ausnahmeoffset: 0000102d Betriebsystemversion: 6.3.9600.2.0.0.272.7 Gebietsschema-ID: 1031 Zusatzinformation 1: 5861 Zusatzinformation 2: 5861822e1919d7c014bbb064c64908b2 Zusatzinformation 3: 9044 Zusatzinformation 4: 904415419f02c4ad4d39c4867383d25a and the script is:

#!/usr/bin/perl -X # -- # Copyright (C) 2001-2016 OTRS AG, http://otrs.com/ # -- # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU AFFERO General Public License as publi +shed by # the Free Software Foundation; either version 3 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public Lic +ense # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-130 +1 USA # or see http://www.gnu.org/licenses/agpl.txt. # -- use strict; use warnings; use utf8; use File::Basename; use FindBin qw($RealBin); use lib dirname($RealBin); use lib dirname($RealBin) . '/Kernel/cpan-lib'; use lib dirname($RealBin) . '/Custom'; use File::Path qw(); use Time::HiRes qw(sleep); use Fcntl qw(:flock); use Kernel::System::ObjectManager; print STDOUT "otrs.Daemon.pl - the OTRS daemon\n"; print STDOUT "Copyright (C) 2001-2016 OTRS AG, http://otrs.com/\n\n"; local $Kernel::OM = Kernel::System::ObjectManager->new( 'Kernel::System::Log' => { LogPrefix => 'OTRS-otrs.Daemon.pl', }, ); # Don't allow to run these scripts as root. if ( $^O ne 'MSWin32' && $> == 0 ) { # $EFFECTIVE_USER_ID die " Cannot run this program as root. Please run it as the 'otrs' user or with the help of su: su -c \"$0\" -s /bin/bash otrs "; } # get config object my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); # get the NodeID from the SysConfig settings, this is used on High Ava +ilability systems. my $NodeID = $ConfigObject->Get('NodeID') || 1; # check NodeID, if does not match its impossible to continue if ( $NodeID !~ m{ \A \d+ \z }xms && $NodeID > 0 && $NodeID < 1000 ) { print STDERR "NodeID '$NodeID' is invalid. Change the NodeID to a +number between 1 and 999."; exit 1; } # get pid directory my $PIDDir = $ConfigObject->Get('Home') . '/var/run/'; my $PIDFile = $PIDDir . "Daemon-NodeID-$NodeID.pid"; my $PIDFH; # get default log directory my $LogDir = $ConfigObject->Get('Daemon::Log::LogPath') || $ConfigObje +ct->Get('Home') . '/var/log/Daemon'; if ( !-d $LogDir ) { File::Path::mkpath( $LogDir, 0, 0770 ); ## no critic if ( !-d $LogDir ) { print STDERR "Failed to create path: $LogDir"; exit 1; } } if ( !@ARGV ) { PrintUsage(); exit 0; } # to wait until all daemon stops (in seconds) my $DaemonStopWait = 30; my $ForceStop; # check for debug mode my %DebugDaemons; my $Debug; if ( lc $ARGV[0] eq 'start' && $ARGV[1] && lc $ARGV[1] eq '--debug' ) { $Debug = 1; # if no more arguments, then use debug mode for all daemons if ( !$ARGV[2] ) { $DebugDaemons{All} = 1; } # otherwise set debug mode specific for named daemons else { ARGINDEX: for my $ArgIndex ( 2 .. 99 ) { # stop checking if there are no more arguments last ARGINDEX if !$ARGV[$ArgIndex]; # remember debug mode for each daemon $DebugDaemons{ $ARGV[$ArgIndex] } = 1; } } } elsif ( lc $ARGV[0] eq 'stop' && $ARGV[1] && lc $ARGV[1] eq '--force' ) { $ForceStop = 1; } elsif ( $ARGV[1] ) { print STDERR "Invalid option: $ARGV[1]\n\n"; PrintUsage(); exit 0; } # check for action if ( lc $ARGV[0] eq 'start' ) { exit 1 if !Start(); exit 0; } elsif ( lc $ARGV[0] eq 'stop' ) { exit 1 if !Stop(); exit 0; } elsif ( lc $ARGV[0] eq 'status' ) { exit 1 if !Status(); exit 0; } else { PrintUsage(); exit 0; } sub PrintUsage { my $UsageText = "Usage:\n"; $UsageText .= " otrs.Daemon.pl <ACTION> [--debug] [--force]\n"; $UsageText .= "\nActions:\n"; $UsageText .= sprintf " %-30s - %s", 'start', 'Starts the daemon p +rocess' . "\n"; $UsageText .= sprintf " %-30s - %s", 'stop', 'Stops the daemon pro +cess' . "\n"; $UsageText .= sprintf " %-30s - %s", 'status', 'Shows daemon proce +ss current state' . "\n"; $UsageText .= sprintf " %-30s - %s", 'help', 'Shows this help scre +en' . "\n"; $UsageText .= "\nNote:\n"; $UsageText .= " In debug mode if a daemon module is specified the debug m +ode will be activated only for that daemon.\n"; $UsageText .= " Debug information is stored in the daemon log file +s localed under: $LogDir\n"; $UsageText .= "\n otrs.Daemon.pl start --debug SchedulerTaskWorker + SchedulerCronTaskManager\n\n"; $UsageText .= "\n Forced stop reduces the time the main daemon waits othe +r daemons to stop from normal 30 seconds to 5.\n"; $UsageText .= "\n otrs.Daemon.pl stop --force\n\n"; print STDOUT "$UsageText\n"; return 1; } sub Start { # create a fork of the current process # parent gets the PID of the child # child gets PID = 0 my $DaemonPID = fork; # check if fork was not possible die "Can not create daemon process: $!" if !defined $DaemonPID || +$DaemonPID < 0; # close parent gracefully exit 0 if $DaemonPID; # lock PID my $LockSuccess = _PIDLock(); if ( !$LockSuccess ) { print "Daemon already running!\n"; exit 0; } # get daemon modules from SysConfig my $DaemonModuleConfig = $Kernel::OM->Get('Kernel::Config')->Get(' +DaemonModules') || {}; # create daemon module hash my %DaemonModules; MODULE: for my $Module ( sort keys %{$DaemonModuleConfig} ) { next MODULE if !$Module; next MODULE if !$DaemonModuleConfig->{$Module}; next MODULE if ref $DaemonModuleConfig->{$Module} ne 'HASH'; next MODULE if !$DaemonModuleConfig->{$Module}->{Module}; $DaemonModules{ $DaemonModuleConfig->{$Module}->{Module} } = { PID => 0, Name => $Module, }; } my $DaemonChecker = 1; local $SIG{INT} = sub { $DaemonChecker = 0; }; local $SIG{TERM} = sub { $DaemonChecker = 0; $DaemonStopWait = 5; +}; local $SIG{CHLD} = "IGNORE"; print STDOUT "Daemon started\n"; if ($Debug) { print STDOUT "\nDebug information is stored in the daemon log +files localed under: $LogDir\n\n"; } while ($DaemonChecker) { MODULE: for my $Module ( sort keys %DaemonModules ) { next MODULE if !$Module; # check if daemon is still alive if ( $DaemonModules{$Module}->{PID} && !kill 0, $DaemonMod +ules{$Module}->{PID} ) { $DaemonModules{$Module}->{PID} = 0; } next MODULE if $DaemonModules{$Module}->{PID}; # fork daemon process my $ChildPID = fork; if ( !$ChildPID ) { my $ChildRun = 1; local $SIG{INT} = sub { $ChildRun = 0; }; local $SIG{TERM} = sub { $ChildRun = 0; }; local $SIG{CHLD} = "IGNORE"; # define the ZZZ files my @ZZZFiles = ( 'ZZZAAuto.pm', 'ZZZAuto.pm', ); # reload the ZZZ files (mod_perl workaround) for my $ZZZFile (@ZZZFiles) { PREFIX: for my $Prefix (@INC) { my $File = $Prefix . '/Kernel/Config/Files/' . + $ZZZFile; next PREFIX if !-f $File; do $File; last PREFIX; } } local $Kernel::OM = Kernel::System::ObjectManager->new +( 'Kernel::System::Log' => { LogPrefix => "OTRS-otrs.Daemon.pl - Daemon $Mo +dule", }, ); # disable in memory cache because many processes runs +at the same time $Kernel::OM->Get('Kernel::System::Cache')->Configure( CacheInMemory => 0, CacheInBackend => 1, ); # set daemon log files _LogFilesSet( Module => $DaemonModules{$Module}->{Name} ); my $DaemonObject; LOOP: while ($ChildRun) { # create daemon object if not exists eval { if ( !$DaemonObject && ( $DebugDaemons{All} || $DebugDaemons{ +$DaemonModules{$Module}->{Name} } ) ) { $Kernel::OM->ObjectParamAdd( $Module => { Debug => 1, }, ); } $DaemonObject ||= $Kernel::OM->Get($Module); }; # wait 10 seconds if creation of object is not pos +sible if ( !$DaemonObject ) { sleep 10; last LOOP; } METHOD: for my $Method ( 'PreRun', 'Run', 'PostRun' ) { last LOOP if !eval { $DaemonObject->$Method() +}; } } exit 0; } else { if ($Debug) { print STDOUT "Registered Daemon $Module with PID $ +ChildPID\n"; } $DaemonModules{$Module}->{PID} = $ChildPID; } } # sleep 0.1 seconds to protect the system of a 100% CPU usage +if one daemon # module is damaged and produces hard errors sleep 0.1; } # send all daemon processes a stop signal MODULE: for my $Module ( sort keys %DaemonModules ) { next MODULE if !$Module; next MODULE if !$DaemonModules{$Module}->{PID}; if ($Debug) { print STDOUT "Send stop signal to $Module with PID $Daemon +Modules{$Module}->{PID}\n"; } kill 2, $DaemonModules{$Module}->{PID}; } # wait for active daemon processes to stop (typically 30 secs, or +just 5 if forced) WAITTIME: for my $WaitTime ( 1 .. $DaemonStopWait ) { my $ProcessesStillRunning; MODULE: for my $Module ( sort keys %DaemonModules ) { next MODULE if !$Module; next MODULE if !$DaemonModules{$Module}->{PID}; # check if PID is still alive if ( !kill 0, $DaemonModules{$Module}->{PID} ) { # remove daemon pid from list $DaemonModules{$Module}->{PID} = 0; } else { $ProcessesStillRunning = 1; if ($Debug) { print STDOUT "Waiting to stop $Module with PID $Da +emonModules{$Module}->{PID}\n"; } } } last WAITTIME if !$ProcessesStillRunning; sleep 1; } # hard kill of all children witch are not stopped after 30 seconds MODULE: for my $Module ( sort keys %DaemonModules ) { next MODULE if !$Module; next MODULE if !$DaemonModules{$Module}->{PID}; print STDOUT "Killing $Module with PID $DaemonModules{$Module} +->{PID}\n"; kill 9, $DaemonModules{$Module}; } # remove current log files without content _LogFilesCleanup(); return 0; } sub Stop { my %Param = @_; my $RunningDaemonPID = _PIDUnlock(); if ($RunningDaemonPID) { if ($ForceStop) { # send TERM signal to running daemon kill 15, $RunningDaemonPID; } else { # send INT signal to running daemon kill 2, $RunningDaemonPID; } } print STDOUT "Daemon stopped\n"; return 1; } sub Status { my %Param = @_; if ( -e $PIDFile ) { # read existing PID file open my $FH, '<', $PIDFile; ## no critic # try to lock the file exclusively if ( !flock( $FH, LOCK_EX | LOCK_NB ) ) { # if no exclusive lock, daemon might be running, send sign +al to the PID my $RegisteredPID = do { local $/; <$FH> }; close $FH; if ($RegisteredPID) { # check if process is running my $RunningPID = kill 0, $RegisteredPID; if ($RunningPID) { print STDOUT "Daemon running\n"; return 1; } } } else { # if exclusive lock is granted, then it is not running close $FH; } } _PIDUnlock(); print STDOUT "Daemon not running\n"; return; } sub _PIDLock { # check pid directory if ( !-e $PIDDir ) { File::Path::mkpath( $PIDDir, 0, 0770 ); ## no critic if ( !-e $PIDDir ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Can't create directory '$PIDDir': $!", ); exit 1; } } if ( !-w $PIDDir ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Don't have write permissions in directory '$P +IDDir': $!", ); exit 1; } if ( -e $PIDFile ) { # read existing PID file open my $FH, '<', $PIDFile; ## no critic # try to get a exclusive of the pid file, if fails daemon is a +lready running if ( !flock( $FH, LOCK_EX | LOCK_NB ) ) { close $FH; return; } my $RegisteredPID = do { local $/; <$FH> }; close $FH; if ($RegisteredPID) { return 1 if $RegisteredPID eq $$; # check if another process is running my $AnotherRunningPID = kill 0, $RegisteredPID; return if $AnotherRunningPID; } } # create new PID file (set exclusive lock while writing the PIDFil +e) open my $FH, '>', $PIDFile || die "Can not create PID file: $PIDFi +le\n"; ## no critic return if !flock( $FH, LOCK_EX | LOCK_NB ); print $FH $$; close $FH; # keep PIDFile shared locked forever open $PIDFH, '<', $PIDFile || die "Can not create PID file: $PIDFi +le\n"; ## no critic return if !flock( $PIDFH, LOCK_SH | LOCK_NB ); return 1; } sub _PIDUnlock { return if !-e $PIDFile; # read existing PID file open my $FH, '<', $PIDFile; + ## no critic # wait if PID is exclusively locked (and do a shared lock for read +ing) flock $FH, LOCK_SH; my $RegisteredPID = do { local $/; <$FH> }; close $FH; unlink $PIDFile; return $RegisteredPID; } sub _LogFilesSet { my %Param = @_; # define log file names my $FileStdOut = "$LogDir/$Param{Module}OUT"; my $FileStdErr = "$LogDir/$Param{Module}ERR"; my $SystemTime = $Kernel::OM->Get('Kernel::System::Time')->SystemT +ime(); # backup old log files use File::Copy qw(move); if ( -e "$FileStdOut.log" ) { move( "$FileStdOut.log", "$FileStdOut-$SystemTime.log" ); } if ( -e "$FileStdErr.log" ) { move( "$FileStdErr.log", "$FileStdErr-$SystemTime.log" ); } # get config object my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); my $RedirectSTDOUT = $ConfigObject->Get('Daemon::Log::STDOUT') || +0; my $RedirectSTDERR = $ConfigObject->Get('Daemon::Log::STDERR') || +0; # redirect STDOUT and STDERR if ($RedirectSTDOUT) { open STDOUT, '>>', "$FileStdOut.log"; } if ($RedirectSTDERR) { open STDERR, '>>', "$FileStdErr.log"; } # remove not needed log files my $DaysToKeep = $ConfigObject->Get('Daemon::Log::DaysToKeep') || +1; my $DaysToKeepTime = $SystemTime - $DaysToKeep * 24 * 60 * 60; my @LogFiles = glob "$LogDir/*.log"; LOGFILE: for my $LogFile (@LogFiles) { # skip if is not a backup file next LOGFILE if ( $LogFile !~ m{(?: .* /)* $Param{Module} (?: +OUT|ERR ) - (\d+) \.log}igmx ); # do not delete files during keep period if they have content next LOGFILE if ( ( $1 > $DaysToKeepTime ) && -s $LogFile ); # delete file if ( !unlink $LogFile ) { # log old backup file cannot be deleted $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Daemon: $Param{Module} could not delete o +ld log file $LogFile! $!", ); } } return 1; } sub _LogFilesCleanup { my %Param = @_; my @LogFiles = glob "$LogDir/*.log"; LOGFILE: for my $LogFile (@LogFiles) { # skip if is not a backup file next LOGFILE if ( $LogFile !~ m{ (?: OUT|ERR ) (?: -\d+)* \.lo +g}igmx ); # do not delete files if they have content next LOGFILE if -s $LogFile; # delete file if ( !unlink $LogFile ) { # log old backup file cannot be deleted $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Daemon: could not delete empty log file $ +LogFile! $!", ); } } return 1; } exit 0;
This script to use OTRS-Daemon, i want to start this feature in cmd like: perl otrs.daemon.pl start but the i got the error. I could use stop or status like perl otrs.daemon.pl stop and it showed me the OTRS-daemon is not running. could anyone help me please? Thanks in advance.

Replies are listed 'Best First'.
Re: Perl Command Line is not working
by soonix (Chancellor) on May 08, 2018 at 16:54 UTC
    The script looks like it is for Linux, but you run it on Windows.

    The script is intended to run on the same computer as the OTRS daemon. OTRS may be able to run on Windows, but that is not recommended.

      actually, i did not know that the script for linux. Thats right, i am trying to run this script on windows machine (on the same machine that hosted otrs system)because OTRS need OTRS Daemon. But is there any solution or tool may be help to let this code to run on windows server 2012 r2? Thanks

        Hmmm ... I don't have any experience with Windows' Linux Subsystem, and that exception code (Ausnahmecode) c0000005 is a more or less general "Access denied".

        I suppose OTRS is running from that subsystem. Do you run the script from a shell in that same subsystem, or from a CMD.EXE prompt? And is the user running the script the same user that OTRS service or daemon is running?

Re: Perl Command Line is not working
by Anonymous Monk on May 11, 2018 at 06:32 UTC