1

I have a script loaded as a service in /etc/init.d/myfile

When I try to start the service I get the error

/etc/init.d/myservice: 21: /etc/init.d/myservice: Syntax error: "(" unexpected

The issue seems to be with the process substitution <( in the source command. I use it without any problem in other scripts to extract variables from my main config file but inside a case statement I don't know how to make it work.

myservice contains:

#!/bin/sh
#/etc/init.d/myservice

### BEGIN INIT INFO
# Provides:          myservice
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: my service
# Description:       Start the myservice service
### END INIT INFO

case "$1" in
  start)
    # start processes
        # Import the following variables from config.conf: cfgfile, dir, bindir
        source <(grep myservice /opt/mysoftware/config.conf | grep -oP '.*(?= #)')
        if [ -f $cfgfile ]
        then
            echo "Starting myservice"
            /usr/bin/screen -U -d -m $bindir/myscript.sh $cfgfile
        else
            echo "myservice could not start because the file $cfgfile is missing"
        fi
    ;;
  stop)
    # kill processes
    echo "Stopping myservice"
    screen -ls | grep Detached | cut -d. -f1 | awk '{print $1}' | xargs kill
    ;;
  restart)
    # kill and restart processes
    /etc/init.d/myservice stop
    /etc/init.d/myservice start
    ;;
  *)
    echo "Usage: /etc/init.d/myservice {start|stop|restart}"
    exit 1
    ;;
esac

exit 0

The file config.conf is a list of variable declarations with a short description and the name of the script using them. I use grep filters to source only the variables I need for a given script.

It looks like this:

var1=value # path to tmp folder   myservice
var2=value # log file name        myservice script1.sh script2.sh
var3=value # prefix for log file  script1.sh script2.sh

Note: The service worked fine before I converted it to start using the config file instead of hardcoded values.

Thank you.

  • 2
    Not all shells support <(...), since it's a nonstandard extension. If you change the first line to #!/bin/bash, does it work? – Mark Plotnick Jan 7 '15 at 21:06
  • Wow... I really missed that! my shebang is set to /bin/bash every were except in this file. I used a template I got online to create it. I shall test and report! :) – TCZ8 Jan 7 '15 at 21:38
  • It works! Thank you so much! Please make your comment into an answer otherwise I will have to accept l0b0's answer. – TCZ8 Jan 7 '15 at 21:44
2

Bash, ksh93, zsh, and other recent shells support process substitution (the <(command) syntax), but it is a non-standard extension. Dash (which is /bin/sh on Ubuntu systems) doesn't support it, and bash when invoked as /bin/sh doesn't, either.

If you have bash available, change the first line of your script to, for example, #!/bin/bash .

[On systems that have bash in a directory on a mountable filesystem, such as /usr/local/bin on some systems, you might need to make sure that filesystem is available before your service is started.]

2

Process substitution is a bashism, but your shebang line is #!/bin/sh. Unless /bin/sh is Bash or some other shell which supports process substitution, that syntax is indeed not supported, as pointed out by @MarkPlotnick.

  • Oh yeah! sure does! l0b0 I will accept your answer if Mark doesnt make his comment into one. Thank you everyone! – TCZ8 Jan 7 '15 at 21:45

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.