sh scripting question

FreeBSD 8.0-RELEASE
$SHELL: csh

With this simple script:
Code:
#! /bin/sh
# jw-rotate.sh
# Apache log rotation script for multiple virtual domains

VIRTUAL_HOST_NAME=( x1.com x2.com x3.com )
echo ${VIRTUAL_HOST_NAME[@]}
Running

Code:
  ./jw-rotate.sh

outputs

Code:
  ./jw-rotate.sh: 5: Syntax error: word unexpected (expecting ")")

Running

Code:
  bash ./jw-rotate.sh

outputs

Code:
  x1.com x2.com x3.com


Apparently, from post elsewhere, this is a FreeBSD anomaly, does not error on Linux.

I'm confused. Can anyone provide an explanation for this?

Thanks

J
 
It's not a FreeBSD anomaly. Bourne shell simply doesn't support arrays. Bash shell does support arrays. You will either need to use bash for your script or not use arrays.

What is arguably an anomaly is linux's practise of making /bin/sh link to a bash shell. /bin/sh should be a Bourne shell, and linking it to a bash shell confuses people like you into thinking arrays are valid syntax for /bin/sh.
 
aragon said:
What is arguably an anomaly is linux's practise of making /bin/sh link to a bash shell.

Hear hear. Not arguably: definitely!
 
Thanks for the reply/education.

I am currently using both newsyslog and apache rotatelogs for different purposes. Both have a limitation (I think) that inspires me to right my own log rotation script.

I have several virtual hosts on the same server, managed for different clients, with separate access_log files. I am writing the script to move and compress the log file with the following naming convention:

domain_access_log-2009-07-27

which is the domain name and date prepended and appended to access_log.

Thanks again
 
jwnetsource said:
I am currently using both newsyslog and apache rotatelogs for different purposes. Both have a limitation (I think) that inspires me to right my own log rotation script.

I have several virtual hosts on the same server, managed for different clients, with separate access_log files. I am writing the script to move and compress the log file with the following naming convention:

domain_access_log-2009-07-27

You can still do this without using arrays. Assuming newsyslog(8) is not going to meet your needs, try something like:
Code:
#!/bin/sh

#
# Functions
#
rotate() {

  # do stuff to rotate ${_logname} here...
  # name it with `date` somehow...
  # ...

}

#
# Main logic
#
_logname=/var/log/something1 ]
 
One can also do this:

Code:
domains="domain1.com domain2.com domain3.com"
for domain in ${domains}; do
  rotate ${domain}
done
 
Aragon, how did you get my log rotation script :p

Seriously, that is the way I write my Apache log rotation scripts for multiple domains. But sh and bash does have a 256 byte variable size limit! Just keep a watch for that and everything will be OK.
 
Or that:

Code:
while read domain
do
  if [ -n "$domain" -a "x${domain#[#]}" = "x$domain" ]
  then
    rotate "${domain}"
  fi
done <<'EOF'

# comment
domain1.com
domain2.com
domain3.com

EOF
 
lme@ said:
I wonder where you got 8.0-RELEASE from. ;-)

First, thanks all for the log rotation advice!

Regarding FreeBSD 8.0-RELEASE, keeping in mind that I wander through Unix with both fear and excitement(kinda like spelunking with weak batteries), and that I was going through life fat, dumb, and happy, running 7.0-RELEASE.

Then one day, for kicks and grins, I decided to customize my kernel. So, I updated all the ports:

Code:
    *default host=cvsup.FreeBSD.org
    *default base=/usr
    *default prefix=/usr
    *default release=cvs tag=RELENG_7
    *default delete use-rel-suffix
    *default compress
    *default tag=.
    src-all
    ports-all tag=.
    doc-all tag=.
    cvsroot-all


Then I tweaked make.conf and rebuilt world and kernel as per the handbook.

Somewhere throughout this process the /etc/motd file was modified (not by me) and, Voila, when I rebooted and logged in, the console said I had FreeBSD 8.0-RELEASE.


Do I have FreeBSD 8.0-RELEASE or is it still 7?
 
jwnetsource, that's no surprising. You've specified tag with collection *default twice.
jwnetsource said:
Code:
*default release=cvs tag=RELENG_7
*default tag=.
The last one takes precedence.
 
Yep, tag=. at this moment is 8.0-CURRENT. When 8.0 gets released it may be a good idea to change it to RELENG_8, which will keep you on 8.0-STABLE. Or to RELENG_8_0, which will keep you on 8.0-RELEASE.
 
Sorry to be off topic, but since we are:

I'll leave it as is until 8 is released, then change to read:

Code:
    *default host=cvsup.FreeBSD.org
    *default base=/usr
    *default prefix=/usr
    *default release=cvs tag=RELENG_8_0
    *default delete use-rel-suffix
    *default compress
    *default tag=.
    src-all
    doc-all tag=.
    cvsroot-all

Thanks much
 
Or that:

Code:
while read domain
do
  if [ -n "$domain" -a "x${domain#[#]}" = "x$domain" ]
  then
    rotate "${domain}"
  fi
done <<'EOF'

# comment
domain1.com
domain2.com
domain3.com

EOF
This is actually a quite useful workaround for the lack of arrays in the Bourne shell. Consider the following method of passing through two parallel lists more than once. Disclaimer: I haven't actually run the code that I'm typing here, but I've run code quite like it. Note that it comes dangerously close to making function onepass a higher order function.
Code:
#!/bin/sh

onepass()
{
  if [ "$1" = firstsecond ]
  then
    while read FIRST
    do
      read SECOND
      $2 $FIRST $SECOND
    done
  elif [ "$1" = secondfirst ]
  then
    while read FIRST
    do
      read SECOND
      $2 $SECOND $FIRST
    done
  elif [ "$1" = secondonly ]
  then
    while read FIRST
    do
      read SECOND
      $2 $SECOND
    done
  elif [ "$1" = echosecond ]
  then
    while read FIRST
    do
      read SECOND
      echo $SECOND
    done
  else
    echo "invalid verb $1 to function onepass" >&2
    exit 1
  fi<<EOD
alpha-first
alpha-second
beta-first
beta-second
gamma-first
gamma-second
delta-first
delta-second
epsilon-first
epsilon-second
EOD
}

onepass firstsecond "cp -av"
onepass secondonly "chown home:home -v"
onepass secondonly "chmod 755 -v"
mkdir something.d
cp -av $(onepass echosecond) something.d
 
Back
Top