Shell 'Garbage' output during script execution (via cron)

I have this script which checks for updates on my host system and on my jails:
Code:
#!/usr/local/bin/bash
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin"

# Updaten en rapporteren Ports Tree host system:
portsnap cron update && {
    echo -e "Packages te updaten voor host system:\n"
    pkg version -l '<' || {
    echo -e "Fout tijdens tonen te updaten packages.\n"
    }
} || {
    echo -e "Fout tijdens updaten Ports Tree van host system.\n"
}

# Updaten en rapporteren Ports Tree jails:
qjail update -P && {
    for JID in $(jls | cut -f 2 -w | tail -n +2)
    do
    JAILHOST=$(jexec $JID hostname)
    echo -e "Packages te updaten voor jail $JAILHOST ($JID):\n"
    (jexec $JID pkg version -l '<') || {
       echo -e "Fout tijdens tonen te updaten packages.\n"
    }
    done
} || {
    echo -e "Fout tijdens updaten ports tree voor jails.\n"
}

Script is being executed as a cron job.

The script seems to be producing 'garbage' output like in the image.

Was this way in 10.1-RELEASE and 10.3-RELEASE. After updating to 11.0-RELEASE it was still there. Though not always. But most of the time. Garbage seems to be put in different places inside the e-mail I'm getting via cron output. It is not really random garbage because it always outputs my external hostname and IP-address. Anyone have an idea what is producing this kind of output?

See image below for sample of e-mail produced by script:

updatescript-garbage.png
 
You should have a closer look on how cron works. Using a bash script and setting environment variables in it call for trouble. cron(8) has it's own environment based on sh(1).

What cronfile do you use? You should avoid to use /etc/crontab but use a user's cronfile instead. See crontab(1). You can set environment variables like PATH in the crontab file.

Hint: For debugging (i.e are variables, files properly used, etc.) you can print to a file giving you the infos you need. That always helps especially when testing things like cronjobs.
 
Nothing written about not being able to use other shells for executing a cron-script in those manual pages you are referring to.

Using /etc/crontab has nothing to do with the garbage output I suppose. But I will keep it in consideration.
 
I think you are right getopt. It is at least good practice to use a user crontab file instead of the system-wide /etc/crontab file. So now I'm using crontab -e and put this before the scheduling of the script:

Code:
SHELL=/usr/local/bin/bash
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"

Now I'll wait and see if this changes things for the better.
 
You can even go one step further and use /bin/sh instead of /usr/local/bin/bash. In contrast to /usr/local/bin/bash the standard shell /bin/sh is always available. In case you might not need specific features of /usr/local/bin/bash for all scripts it is good oppertunity to give /bin/sh a try. I am sure you can manage that.
 
I know chrbr. It is more of a repetition thing for me to use /usr/local/bin/bash instead of /bin/sh. I can do without I guess but I prefer to repeat my usage of /usr/local/bin/bash.
 
There is some weird stuff going on in that script. Why use echo -e to suppress the linefeed and then manually add it into the string? I will also suggest using sh to avoid bash.

Add some simple debug output between the various steps (echo "beginning portsnap") to show which part is producing that output.

Also, I recommend using full paths to commands. Not only does this make setting a path unnecessary, it makes certain the script is running the commands you wanted it to run, rather than a different command with the same name. So rather than just portsnap, use:
Code:
PORTSNAP="/usr/bin/portsnap"
${PORTSNAP} cron update
 
The garbage output shows up in several parts of the mails seemingly random. Sometimes in 'this' part and in a later mail in some other part. But never consistent.
 
Back
Top