[SOLVED] Inconsistent behaviour of shell script

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
gargoil666uk
Level 1
Level 1
Posts: 41
Joined: Fri Aug 15, 2014 9:26 am
Location: United Kingdom, GMT+0:00
Contact:

[SOLVED] Inconsistent behaviour of shell script

Post by gargoil666uk »

Here's a strange one that I cannot fathom?

I have a small "stop script" named "/home/gjd/jobs/cctv0.sh" that creates a halt trigger file to stop processing of a loop in another job. The small "stop script" looks like this:

Code: Select all

#!/bin/bash
#
. /home/gjd/jobs/coredecs.sh   # include common variables from master declarations file
. /home/gjd/jobs/cctvdecs.sh   # include common variables from camera declarations file
# ***********************************************************************
# *  Warning: creation of a shutdown file will stop ALL instances.      *
# ***********************************************************************
touch $STOPTRIGGERFILE
exit $?
and this creates the trigger file "/home/gjd/cctv/cctv0.txt" which causes other jobs to stop as required.


This script contains an include file thus:

Code: Select all

. /home/gjd/jobs/cctvdecs.sh
, as shown above
and the cctvdecs.sh looks like this:

Code: Select all

#!/bin/bash
#

# Declare the the base name for references to cameras and also for directory naming.
# This isolates such references so that this value can be changed easily in the event of future renaming.
export CCTVBASE=cctv

# Define variable representing the source directory for zipped archive files
export ARCHIVEPATH=/home/gjd/${CCTVBASE}

# Define variable representing the directory for final generated movie files
export MOVIEPATH=/home/gjd/Videos

# Define variable representing the filename that will act as the trigger file to stop other jobs
export STOPTRIGGERFILE=$ARCHIVEPATH/${CCTVBASE}0.txt

# Define the time of day group identities using an array for convenience
export GROUPARRAY=(g0dark g1dawn g2morn1 g3morn2 g4noon g5noonplus g6pm1 g7pm2 g8pm3 g9sleep)

...etc...
I include this file in various other scripts that I run manually on the command line. They all work fine.


The odd behaviour with the small "stop script" is that if I execute it directly at the command line it creates the trigger file. Likewise if I schedule it using cron. In both cases no errors are reported.
However, when I use an ad-hoc execution thus:

Code: Select all

at -f/home/gjd/jobs/cctv0.sh now + 1 min
the job appears to stall, or at least it doesn't run to completion.

After some debugging I have managed to determine that the include file variables are defined successfully up to and including the line:

Code: Select all

export STOPTRIGGERFILE etc.
but the next line appears to be causing the stall:

Code: Select all

export GROUPARRAY etc.

No errors are reported anywhere including in '/var/log/syslog'.
No "Stopped jobs" are reported on exit.

So the question remains, why does the above work okay under direct execution and using cron, but not using 'at'?
Can somebody more knowledgeable please enlighten me?

Thanks guys.

---

Linux Mint 18.3 Cinnamon 64-bit
Cinnamon Version: 3.6.7
Linux Kernel: 4.10.0-38-generic
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 2 times in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
rene
Level 20
Level 20
Posts: 12240
Joined: Sun Mar 27, 2016 6:58 pm

Re: Inconsistent behaviour of shell script

Post by rene »

The GROUPARRAY line declares an array, and arrays are not POSIX. And are in fact unsupported by the on debian/ubuntu/mint used /bin/sh shelll "dash":

Code: Select all

rene@hp8k:~$ sh
$ FOO=(foo bar)                        
sh: 1: Syntax error: "(" unexpected
Now, other than "at" also "cron" normally uses /bin/sh rather than, say, /bin/bash but you may have adjusted that in the case of cron...
User avatar
xenopeek
Level 25
Level 25
Posts: 29459
Joined: Wed Jul 06, 2011 3:58 am

Re: Inconsistent behaviour of shell script

Post by xenopeek »

But the hashbang line for the scripts is #!/bin/bash, so dash should be loading bash to execute the script.
Image
rene
Level 20
Level 20
Posts: 12240
Joined: Sun Mar 27, 2016 6:58 pm

Re: Inconsistent behaviour of shell script

Post by rene »

Yes, but he is invoking "at" with "-f .../cctv0.sh". "at" doesn't schedule a run of .../cctv0.sh as such but "sources it" into a #!/bin/sh script that's written to /var/spool/cron/atjobs for later execution. At that later time that /bin/sh script, .../cctv0.sh as included into /var/spool/cron/atjobs/foo, is executed, i.e, through /bin/sh with no /bin/bash in sight (.../cctv0.sh itself then sources the problematic .../cctvdecl.sh fragment but at that point the game's over already: it could of course not execute ..../cctvdecl.sh anyway since its setup of environment would die alongside its own subshell).

Yes, "at" is a horrid bit of infrastructure.
gargoil666uk
Level 1
Level 1
Posts: 41
Joined: Fri Aug 15, 2014 9:26 am
Location: United Kingdom, GMT+0:00
Contact:

Re: Inconsistent behaviour of shell script

Post by gargoil666uk »

Thanks for confirming my suspicions. I suspected that it might have something to do with the specific shell/sub-shell.
I’ve since checked a few other of my scripts and some of them suffer the same behaviour that I hadn’t noticed previously.
What can I say, I’m a fan of 'at' from my days working with Unix systems. Now I’ve learned another valuable lesson.
rene
Level 20
Level 20
Posts: 12240
Joined: Sun Mar 27, 2016 6:58 pm

Re: Inconsistent behaviour of shell script

Post by rene »

Let me add that the easiest way to get things working is simply echo /home/gjd/jobs/cctv0.sh | at now + 1 min, assuming that /home/gjd/jobs/cctv0.sh is in fact executable, echo bash /home/gjd/jobs/cctv0.sh | at now + 1 min if not. It is then executed through bash...

Also, that you may want to set up local mail for use by e.g. cron and at:

Code: Select all

sudo apt-get install postfix
Pick "local only" and for example <hostname>.local as the mail name. Optionally, edit as root /etc/aliases and add root: <username> and run sudo newaliases so as to have root-destined mail delivered to you yourself.

To read it, sudo apt-get install mailutils and use mail from the command line without any further configuration. Of course sudo mail if you did not elect to have mail for root delivered to you.

Or if you did, Thunderbird -> Edit -> Account settings -> Account actions -> Add other account -> UNIX Mailspool (Movemail) -> "Your Name", "<username>@<hostname>.local" -> Next -> Next -> Finish. Optionally add outgoing server "Postfix" at "localhost" port 25 and set it as the account's SMTP server if you also want to send local mail from within Thunderbird using the just added account. Set the account to check for new mail regularly (10 minute default) and/or check manually when expecting local mail.

This would've in this case for example mailed you about the syntax error...
Locked

Return to “Scripts & Bash”