7
\$\begingroup\$

I have a shell script which is being used on an embedded human machine interface (HMI). This script is used to copy a few files from a USB stick to a different place on the device, but with multiple instances of the same file under different names.

If it helps:

  • OS is Unix-like (BusyBox v1.11.2)
  • Commands available are located here
  • The filesystem is JFFS2

Any thoughts on improvements/optimizations would be appreciated.

#! /bin/sh
echo "
****Project Customisation Daemon STARTING****
"
echo "Main Background:"
# First, check the new image exists
if [ -s "/disk/usbsda1/New_Main.png" ] 
then
   echo " -> Found new file to be used!"
   # Check if our directory is already present
   if [ -d "/opt/pclient/projekte/Main/" ]
   then
      # If our directory exists, remove the files
      echo " -> Found old directory, removing contents!"
      rm -rf /opt/pclient/projekte/Main/*
   else
      # If the directory isnt present, create it!
      echo " -> Creating new directory!"
      mkdir -p /opt/pclient/projekte/Main/
   fi   
   # Now copy our files!
   echo " -> Copying new files, please wait!"
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page2.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page3.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page4.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page5.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page6.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page7.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page8.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page9.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page10.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page11.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page12.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page13.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page14.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page15.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page16.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page17.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page18.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page19.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page20.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page21.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page22.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page23.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page24.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page25.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page26.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page27.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page28.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page29.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page30.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page31.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page32.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page33.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page34.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page35.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page36.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page38.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page62.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page63.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page64.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page65.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page66.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page67.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page68.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page69.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page610.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page611.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page615.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page616.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page618.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page619.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page620.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page621.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page622.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page623.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page624.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page626.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page627.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page628.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page629.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page630.png
   cp /disk/usbsda1/New_Main.png /opt/pclient/projekte/Main/Main_Page631.png
else
   echo " -> Could not find new image to use, skipping!"
fi

# Inform the user that the files have been created
echo " -> All background images created!"
echo " -> Now copying to project folder!"
# move the files into the appropriate place
cp /opt/pclient/projekte/Main/* /opt/pclient/projekte/default_prj/terminal_files/

# Next we need to create copies of any additional images we will need
echo "Help Pages:"
# First, check the new image exists
echo " -> Now creating Help logos"
if [ -s "/disk/usbsda1/New_Help.png" ] 
then
   echo " -> Found new file to be used!"
   # Check if our directory is already present
   if [ -d "/opt/pclient/projekte/Help/" ]
   then
      # If our directory exists, remove the files
      echo " -> Found old directory, removing contents!"
      rm -rf /opt/pclient/projekte/Help/*
   else
      # If the directory isnt present, create it!
      echo " -> Creating new directory!"
      mkdir -p /opt/pclient/projekte/Help/
   fi   
   # Now copy our files!
   echo " -> Copying new files, please wait!"
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page2.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page3.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page4.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page5.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page6.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page7.png
   cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page8.png
else
   echo " -> Could not find new image to use, skipping!"
fi

# Inform the user that the files have been created
echo " -> Applying changes to project!"
# move the files into the appropriate place
cp /opt/pclient/projekte/Help/* /opt/pclient/projekte/default_prj/terminal_files/
echo "Icon Pages:"
# Check the new Icon pages exists
echo " -> Now creating Icon logos"
if [ -s "/disk/usbsda1/New_Icon.png" ] 
then
   echo " -> Found new file to be used!"
   # Check if our directory is already present
   if [ -d "/opt/pclient/projekte/Icon/" ]
   then
      # If our directory exists, remove the files
      echo " -> Found old directory, removing contents!"
      rm -rf /opt/pclient/projekte/Icon/*
   else
      # If the directory isnt present, create it!
      echo " -> Creating new directory!"
      mkdir -p /opt/pclient/projekte/Icon/
   fi   
   # Now copy our files!
   echo " -> Copying new files, please wait!"
   cp /disk/usbsda1/New_Icon.png /opt/pclient/projekte/Icon/Icon_Page.png
   cp /disk/usbsda1/New_Icon.png /opt/pclient/projekte/Icon/Icon_Page2.png

else
   echo " -> Could not find new image to use, skipping!"
fi

# Inform the user that the files have been created
echo " -> Applying changes to project!"
# move the files into the appropriate place
cp /opt/pclient/projekte/Icon/* /opt/pclient/projekte/default_prj/terminal_files/

echo "Additional Logos:"
# Check the new logo page exists
echo " -> Now creating Logo"
if [ -s "/disk/usbsda1/New_Logo.png" ] 
then
   echo " -> Found new file to be used!"
   # Check if our directory is already present
   if [ -d "/opt/pclient/projekte/Logo/" ]
   then
      # If our directory exists, remove the files
      echo " -> Found old directory, removing contents!"
      rm -rf /opt/pclient/projekte/Logo/*
   else
      # If the directory isnt present, create it!
      echo " -> Creating new directory!"
      mkdir -p /opt/pclient/projekte/Logo/
   fi   
   # Now copy our files!
   echo " -> Copying new files, please wait!"
   cp /disk/usbsda1/New_Logo.png /opt/pclient/projekte/Logo/Logo2.png
else
   echo " -> Could not find new image to use, skipping!"
fi

# Inform the user that the files have been created
echo " -> Applying changes to project!"
# move the files into the appropriate place
cp /opt/pclient/projekte/Logo/* /opt/pclient/projekte/default_prj/terminal_files/

# Next we need to copy the boot logo and startup screen logo
echo "Boot Logos:"
# First, check the new image exists
echo " -> Now creating boot logos"
if [ -s "/disk/usbsda1/New_Boot.png" ] 
then
   echo " -> Found new file to be used!"
   # Check if our directory is already present
   if [ -d "/opt/pclient/projekte/Boot/" ]
   then
      # If our directory exists, remove the files
      echo " -> Found old directory, removing contents!"
      rm -rf /opt/pclient/projekte/Boot/*
   else
      # If the directory isnt present, create it!
      echo " -> Creating new directory!"
      mkdir -p /opt/pclient/projekte/Boot/
   fi   
   # Now copy our files!
   echo " -> Copying new files, please wait!"
   cp /disk/usbsda1/New_Boot.png /opt/pclient/projekte/Boot/loading_screen.png
else
   echo " -> Could not find new image to use, skipping!"
fi

# Inform the user that the files have been created
echo " -> Applying changes to project!"
# move the files into the appropriate place
cp /opt/pclient/projekte/Boot/* /opt/pclient/projekte/default_prj/terminal_files/additional_files
setbootlogo /opt/pclient/projekte/default_prj/terminal_files/additional_files/loading_screen.png


echo "Wrapping up:"
# Fully tidy up, by removing any un needed file paths
echo " -> Removing un-needed files!"
rm -rf /opt/pclient/projekte/Main/*
rm -rf /opt/pclient/projekte/Boot/*
rm -rf /opt/pclient/projekte/Help/*
rm -rf /opt/pclient/projekte/Icon/*
rm -rf /opt/pclient/projekte/Logo/*
echo " -> Removing un-needed directories!"
rmdir /opt/pclient/projekte/Main
rmdir /opt/pclient/projekte/Boot
rmdir /opt/pclient/projekte/Help
rmdir /opt/pclient/projekte/Icon
rmdir /opt/pclient/projekte/Logo

echo "
****Project Customisation Daemon COMPLETE****
"
\$\endgroup\$
1
+100
\$\begingroup\$

Extract repeated values to variables

The most important thing is to avoid copy-pasting absolute paths everywhere. If the path ever changes it's a hassle to replace all strings in the script. It also makes it difficult to test the script with dummy directories instead of the real ones. So, always constants in variables, for example:

SRCDIR=/disk/usbsda1
WORKDIR=/opt/pclient/projekte
DSTDIR=/opt/pclient/projekte/default_prj/terminal_files

Similarly, when using these constants repeatedly, it's good to introduce a temporary variable to capture the common element. For example, instead of this:

cp "$SRCDIR"/New_Main.png "$WORKDIR"/Main/Main_Page.png
cp "$SRCDIR"/New_Main.png "$WORKDIR"/Main/Main_Page2.png
cp "$SRCDIR"/New_Main.png "$WORKDIR"/Main/Main_Page3.png

I would do like this:

IMAGE="$SRCDIR"/New_Main.png
DIR="$WORKDIR"/Main
cp "$IMAGE" "$DIR"/Main_Page.png
cp "$IMAGE" "$DIR"/Main_Page2.png
cp "$IMAGE" "$DIR"/Main_Page3.png

These kind of extractions to variables make the script more flexible, as you can change a path in one place and it will affect all the places where it's used. Another good thing is that a variable serves as a label of the purpose, the intention, which can be often more descriptive than the actual hardcoded string.

A note about quoting

I didn't quote SRCDIR=/disk/usbsda1 because it's unnecessary. But afterwards I quote "$SRCDIR" everywhere, in case "somebody" might ever set SRCDIR to a path with spaces. This is good precaution. Finally, these are equivalent:

cp "$IMAGE" "$DIR"/Main_Page.png
cp "$IMAGE" "$DIR/Main_Page.png"

Extract repeated logic to functions

In the processing each of the image types, you use the same kind of logic to check if a directory exists and remove its contents, or else create the directory. This could be in a function:

prepare_dir() {
    DIR=$1
    if [ -d "$DIR" ]
    then
        echo " -> Found old directory, removing contents!"
        rm -rf "$DIR"/*
    else
        echo " -> Creating new directory!"
        mkdir -p "$DIR"
    fi   
}

You can call this with prepare_dir "$WORKDIR"/Main, prepare_dir "$WORKDIR"/Help, prepare_dir "$WORKDIR"/Logo, and so on, reducing duplication and shortening your code.

Excessive comments

Your many echo statements already explain what the code does. The comments are redundant, I would remove all of them.

Moving code to the right enclosing block

In the processing of some of the image types, you run a cp after the main processing, even if a matching file did not exist, for example:

echo " -> Now creating Help logos"
if [ -s "/disk/usbsda1/New_Help.png" ] 
then
    echo " -> Found new file to be used!"
    # ...
    echo " -> Copying new files, please wait!"
    cp /disk/usbsda1/New_Help.png /opt/pclient/projekte/Help/Help_Page.png
    # ...
else
    echo " -> Could not find new image to use, skipping!"
fi

echo " -> Applying changes to project!"
cp /opt/pclient/projekte/Help/* /opt/pclient/projekte/default_prj/terminal_files/

The last cp is outside of the if-then block. But intuitively, it seems that if the if condition was false, then this last cp would find no files to copy, in which case it should be within the then block above.

Misc

Do you really need to copy files to a temporary directory first? Based on just the script you posted, this seems pointless, you could have copied directly to the destination.

Suggested implementation

Applying the suggestions above, I would rewrite your script like this (but without spelling out all the individual files in some of the longer blocks):

#! /bin/sh

SRCDIR=/disk/usbsda1
WORKDIR=/opt/pclient/projekte
DSTDIR=/opt/pclient/projekte/default_prj/terminal_files

prepare_dir() {
    DIR=$1
    if [ -d "$DIR" ]
    then
        echo " -> Found old directory, removing contents!"
        rm -rf "$DIR"/*
    else
        echo " -> Creating new directory!"
        mkdir -p "$DIR"
    fi   
}

echo "
****Project Customisation Script STARTING****
"
echo "Main Background:"
IMAGE="$SRCDIR"/New_Main.png
if [ -s "$IMAGE" ] 
then
    echo " -> Found new file to be used!"
    DIR="$WORKDIR"/Main
    prepare_dir "$DIR"

    echo " -> Copying new files, please wait!"
    cp "$IMAGE" "$DIR"/Main_Page.png
    cp "$IMAGE" "$DIR"/Main_Page2.png
    # ... and so on ...

    echo " -> All background images created!"
    echo " -> Now copying to project folder!"
    cp "$DIR"/* "$DSTDIR"
else
    echo " -> Could not find new image to use, skipping!"
fi

echo "Help Pages:"
echo " -> Now creating Help logos"
IMAGE="$SRCDIR"/New_Help.png
if [ -s "$IMAGE" ] 
then
    echo " -> Found new file to be used!"
    DIR="$WORKDIR"/Help
    prepare_dir "$DIR"

    echo " -> Copying new files, please wait!"
    cp "$IMAGE" "$DIR"/Help_Page.png
    cp "$IMAGE" "$DIR"/Help_Page2.png
    # ... and so on ...

    echo " -> Applying changes to project!"
    cp "$DIR"/* "$DSTDIR"
else
    echo " -> Could not find new image to use, skipping!"
fi

echo "Icon Pages:"
IMAGE="$SRCDIR"/New_Icon.png
if [ -s "$IMAGE" ] 
then
    echo " -> Found new file to be used!"
    DIR="$WORKDIR"/Icon
    prepare_dir "$DIR"

    echo " -> Copying new files, please wait!"
    cp "$IMAGE" "$DIR"/Icon_Page.png
    cp "$IMAGE" "$DIR"/Icon_Page2.png

    echo " -> Applying changes to project!"
    cp "$DIR"/* "$DSTDIR"
else
    echo " -> Could not find new image to use, skipping!"
fi

echo "Additional Logos:"
echo " -> Now creating Logo"
IMAGE="$SRCDIR"/New_Logo.png
if [ -s "$IMAGE" ] 
then
    echo " -> Found new file to be used!"
    DIR="$WORKDIR"/Logo
    prepare_dir "$DIR"

    echo " -> Copying new files, please wait!"
    cp "$IMAGE" "$DIR"/Logo2.png

    echo " -> Applying changes to project!"
    cp "$DIR"/* "$DSTDIR"
else
    echo " -> Could not find new image to use, skipping!"
fi

echo "Boot Logos:"
echo " -> Now creating boot logos"
IMAGE="$SRCDIR"/New_Boot.png
if [ -s "$IMAGE" ] 
then
    echo " -> Found new file to be used!"
    DIR="$WORKDIR"/Boot
    prepare_dir "$DIR"

    echo " -> Copying new files, please wait!"
    cp "$IMAGE" "$DIR"/loading_screen.png

    echo " -> Applying changes to project!"
    cp "$DIR"/* "$DSTDIR"/additional_files
else
    echo " -> Could not find new image to use, skipping!"
fi

setbootlogo "$DSTDIR"/additional_files/loading_screen.png

echo "Wrapping up:"
# Fully tidy up, by removing any un needed file paths
echo " -> Removing un-needed files!"
rm -rf "$WORKDIR"/Main/*
rm -rf "$WORKDIR"/Boot/*
rm -rf "$WORKDIR"/Help/*
rm -rf "$WORKDIR"/Icon/*
rm -rf "$WORKDIR"/Logo/*
echo " -> Removing un-needed directories!"
rmdir "$DSTDIR"/Main
rmdir "$DSTDIR"/Boot
rmdir "$DSTDIR"/Help
rmdir "$DSTDIR"/Icon
rmdir "$DSTDIR"/Logo

echo "
****Project Customisation Script COMPLETE****
"

Looking at this code, there's still a lot of repetition: the processing of each image type looks very similar. You could go a step further and generalize that logic too, for example:

process_image() {
    TITLE=$1; shift
    IMAGE=$1; shift
    DIR=$1; shift
    CP_FUNCTION=$1; shift
    echo $TITLE
    if [ -s "$IMAGE" ] 
    then
        echo " -> Found new file to be used!"
        prepare_dir "$DIR"

        echo " -> Copying new files, please wait!"
        $CP_FUNCTION "$IMAGE" "$DIR"

        echo " -> Applying changes to project!"
        cp "$DIR"/* "$DSTDIR"
    else
        echo " -> Could not find new image to use, skipping!"
    fi
}

cp_main() {
    IMAGE=$1; shift
    DIR=$1; shift
    cp "$IMAGE" "$DIR"/Main_Page.png
    cp "$IMAGE" "$DIR"/Main_Page2.png
    # ... and so on ...
}

process_image "Main Background:" "$SRCDIR"/New_Main.png "$WORKDIR"/Main cp_main

cp_help() {
    IMAGE=$1; shift
    DIR=$1; shift
    cp "$IMAGE" "$DIR"/Help_Page.png
    cp "$IMAGE" "$DIR"/Help_Page2.png
    # ... and so on ...
}

process_image "Help Pages:" "$SRCDIR"/New_Help.png "$WORKDIR"/Help cp_help

... but this risks the script becoming too cryptic. At some point you have to draw the line and find the right balance between optimization and overengineering.

\$\endgroup\$
4
\$\begingroup\$

A few comments. You make many copies of the files but JFFS2 seems to support hard links, so I would use links instead (see man ln and the ln command in the example below). Also you copy all files into temporary directories and then copy them to the target directory. This is unnecessary - just copy one file to the target directory and then link that to the necessary target file names.

I would probably write it using a loop, if your shell allows that. And I would pass the source and maybe target directories into the script, so you would call it as:

myscript /disk/usbsda1/  /opt/pclient/projekte/default_prj/terminal_files/

My scripting is rusty, but here is a naive script using a loop. Script experts can doubtless improve this. Note that the -x on the first line causes the shell to print each command as it is executed.

#! /bin/sh -x

DISK=$1
TARGET=$2

copy_files()
{
    # called as: copy_files sourcedir sourcefile destdir destfile1 destfile2 ...
        SRCDIR=$1
        SRC=$2
        DESTDIR=$3
        shift; shift; shift
        cp $SRCDIR/$SRC $DESTDIR
        for f in $@
        do
                ln $DESTDIR/$SRC $DESTDIR/$f
        done
        rm $DESTDIR/$SRC
}

copy_files $DISK New_Main.png $TARGET Main_Page.png \
    Main_Page2.png \
    Main_Page3.png
\$\endgroup\$
  • \$\begingroup\$ My only question would be: What is the benefit of passing the paths into the script? The script has been specifically used for this one function \$\endgroup\$ – Joshpbarron May 23 '14 at 5:29
  • 3
    \$\begingroup\$ It makes testing easier if the script is not tied to a particular device/path and the script is also more flexible. Hard-coded paths are generally best avoided because they make maintenance harder - eg in your script, if you decide to change the location of files, you need to edit many lines. You could just set the paths at the top of the script (DISK and TARGET variables) with little loss but I really recommend against repeating the paths throughout the script. \$\endgroup\$ – William Morris May 23 '14 at 14:18
  • 1
    \$\begingroup\$ You should make it a habit to double-quote all variables. Otherwise, the script will break if a variable contains a special character. \$\endgroup\$ – 200_success May 26 '14 at 21:40
  • \$\begingroup\$ I have never come across that idea, but clearly you are right. I suppose I am old fashioned, but putting spaces (eg) in paths never seems sensible (and complicates shell commands). \$\endgroup\$ – William Morris May 27 '14 at 0:50
1
\$\begingroup\$

The script output says ****Project Customisation Daemon STARTING****, but I don't believe that your script qualifies as a daemon. A proper daemon in Unix has some specific characteristics, namely that is dissociates itself completely from its parent process. (According to Unix Programming FAQ #1.7, daemonizing a process involes a fork(), setsid(), fork(), chdir(), umask(), and several close() calls.)

Call this program what it is: a "script" or a "process".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.