-1

I have a (.sh) script that:

  • Creates a file
  • Reads a(ll) XML file
  • Writes specific info to a .txt file

When I execute it manually using the ./mappingToText.sh command, a file called autorisaties.txt is created. This file has some of the contents from the xml files.

When I run this same script from the crontab, the file is created, but it is empty (0 bytes). I have found a whole lot of different topics on this issue, and tried a few solutions:

  • I tried using >(>) and 2>&1 to write directly to the file
  • Applied some changes to the code that suppose to work (based on other topics)
  • Using full paths in the script
  • Using this piece of code in the crontab: SHELL=/bin/bash

None have yet solved the problem for me.

Cronjob:

35 11 * * * /opt/IBM/taddm/dist/var/policy/ibmsecauthz/policy/rolemapping/AuthorizationManagerPolicyContextId_role/mappingToText.sh

Script:

#!/bin/bash

#Filepath van logfile
LOGFILE=/opt/IBM/taddm/dist/var/policy/ibmsecauthz/policy/rolemapping/AuthorizationManagerPolicyContextId_role/autorisaties.txt

#Kijken of logfile bestaat
if test -f "$LOGFILE"; then

        #log bestaat dus verwijder deze
        rm $LOGFILE
fi

#log bestaat niet dus maak deze aan
touch $LOGFILE

#geef file rechten (i have been trying/playing around using different users, will prob not use this later)
chmod 777 $LOGFILE #Issue also occurs when not using chmod

#Doorloop alle XML bestanden
for FILE in *;
do
        #Als het bestand "principal" in de naam heeft
        #if [ $FILE  == *"principal"* ]; then
        if echo $FILE | grep -q "principal"; then

                #Naam (String) van de user ophalen uit het XML bestand
                name=$(xmlstarlet sel -T -t -m "//*[local-name()='Subject']/*[local-name()='SubjectMatch']/*[local-name()='AttributeValue']/*[local-name()='DataValue']/*[local-name()='SimpleValue']" -v . $FILE)

                #Rollen (Array) ophalen uit het XML bestand
                roles=$(xmlstarlet sel -T -t -m "//*[local-name()='Condition']/*[local-name()='Apply']/*[local-name()='AttributeValue']/*[local-name()='DataValue']/*[local-name()='SimpleValue']" -v . -n $FILE)

                #Code snippet: sorteren van de array
                IFS=$'\n' sortedRoles=($(sort <<<"${roles[*]}"))
                unset IFS

                #Helper variable
                previousRole=""

                #Doorlopen van de rollen
                for i in "${sortedRoles[@]}"
                do
                        #Omdat rollen soms dubbel in de XML staan
                        if [ "$i" != "$previousRole" ] ; then

                                #Timestamp voor log ophalen
                                date=$(date +%Y-%m-%d_%H:%M:%S)

                                #Underscore (_) vervangen door spatie
                                adjustedDate=${date//[_]/ }

                                #Schrijf autorisaties weg naar logfile
                                echo $adjustedDate " - Naam van gebruiker: " $name " - Rol van gebruiker: " $i >> $LOGFILE
                        fi

                previousRole=$i
                done

        fi

done

How do I make this script work with a cronjob? Thanks

EDIT Triplee mentioned CronJob not running

Following his steps:

  1. Is the Cron daemon running? yes
  2. Is cron working? yes
  3. Is the command working standalone? yes
  4. Can cron run your job? Yes, no errors are found in the cron log
  5. Check permissions Permissions are fine. Can also write to directory
  6. Check paths I am using actual paths, that should be enough right?
  7. Don't suppress output while debugging Tried >>cron.out 2>&1 , see below

crontab -l:

48 12 * * * /opt/IBM/taddm/dist/var/policy/ibmsecauthz/policy/rolemapping/AuthorizationManagerPolicyContextId_role/mappingToText.sh >>/opt/IBM/taddm/dist/var/policy/ibmsecauthz/policy/rolemapping/AuthorizationManagerPolicyContextId_role/cron.out 2>&1

ll:

-rw-r--r--. 1 root     root         0 Jan 13 12:48 autorisaties.txt
-rw-r--r--. 1 root     root         0 Jan 13 12:48 cron.out
Niek Jonkman
  • 1,014
  • 2
  • 13
  • 31
  • 2
    Whatever you are hoping to accomplish, **`chmod 777` is *wrong* and *dangerous.*** You absolutely do not want to grant write access to executable or system files to all users under any circumstances. You will want to revert to sane permissions ASAP (for your use case, probably `chmod 644` or `chmod 664` and learn about the Unix permissions model before you try to use it again. If this happened on a system with Internet access, check whether an intruder could have exploited this to escalate their privileges. Then see if your OS offers a shell interface to the system log facility like `logger` – tripleee Jan 13 '23 at 10:57
  • @tripleee, noted! The host has no internet access. Main reason is laziness. – Niek Jonkman Jan 13 '23 at 11:01
  • 2
    For your actual question, I'm guessing you are somehow hoping that the script will run in a different directory than your home directory; but that's not how `cron` works. – tripleee Jan 13 '23 at 11:03
  • Did you checked if `chmod 777 $LOGFILE` does not run into error, when your script runs as cron job? Cron has a shell of its own. So when you run a cron job it might not have the same environment as when your user executes it. – Hölderlin Jan 13 '23 at 11:05
  • You may be assuming that the environment is setup exactly like how it is in an interactive shell started by the same user. It is probably not. Do a cron job that only dumps (`env > /tmp/mycronenv.$$)` to a file and read that file. – Ted Lyngmo Jan 13 '23 at 11:09
  • @Hölderlin, the issue also occurs when not using chmod. Main reason I used chmod was to check if it would work with the crontab if the logfile was accesible by anyone. – Niek Jonkman Jan 13 '23 at 11:10
  • 1
    Probably see [Cron job not running](https://stackoverflow.com/questions/22743548/cronjob-not-running) for general `cron` troubleshooting. I don't think we can tell you what's wrong based on what you have posted so far. – tripleee Jan 13 '23 at 11:15
  • Keep it simple first. create file and set permission with your user manually, then check if cronjob can r/w file. – Hölderlin Jan 13 '23 at 11:15
  • 1
    Since $LOGFILE is created (but empty), the problem must be in the logic of the script after creation of the file. I suggest that you turn on tracing (`set -x`) and inspect the stderr (which contains the trace of the execution). This should reveal why the script never runs into the branch where `adjustedDate` is calculated. For better debugging, I would also output the working directory (for instance, by doing a `pwd >$LOGFILE` instead of a `touch $LOGFILE`. – user1934428 Jan 13 '23 at 11:27
  • 3
    I will repeat the guess that you are running it in the wrong directory. Where are the files you want to process? In your home directory? How many are there? Is the `cron` job running as the owner of those files? – tripleee Jan 13 '23 at 11:58
  • Duplicate of [What exactly is current working directory?](https://stackoverflow.com/questions/45591428/what-exactly-is-current-working-directory) – tripleee Jan 13 '23 at 12:26

1 Answers1

2

You're using for FILE in * without changing the working directory before. Looks like the script is run from a different working directory by cron.

Have you tried for FILE in /path/to/xml/files/*? Even though you write "I'm using actual paths, right?": Your code does not reflect that at this point.

orithena
  • 1,455
  • 1
  • 10
  • 24