rc.d shell scripts: no extension vs. .sh

ikevin8me

Active Member

Reaction score: 12
Messages: 198

I think I asked this question sometime ago, but I can't find the answer when searching for it. Anyway...

First, I think I know the difference for startup shell scripts located in /etc/rc.d and /usr/local/etc/rc.d. The former is for system scripts while the latter is for user-installed scripts. So, therefore, we should always place scripts in the latter, whether it is for the host or inside a jail. (Let me know me if incorrect...)

Here's my real question: Why do I need to specifically change the name to ".sh" for some scripts to make it run? What's the difference for scripts without filename extensions and those that has to append ".sh" to make it run?
 

T-Daemon

Daemon

Reaction score: 871
Messages: 1,747

Why do I need to specifically change the name to ".sh" for some scripts to make it run?

You don't need to specify a .sh extension to a shell script. The extension of a shell script doesn't determine if it can be run or not. The read and execution permissions of the file owner and/or group member and/or others do. chmod(1)

/etc/rc.d
Code:
-r-xr-xr-x  DAEMON*
-r-xr-xr-x  FILESYSTEMS*
-r-xr-xr-x  LOGIN*
-r-xr-xr-x  NETWORKING*
-r-xr-xr-x  SERVERS*
-r-xr-xr-x  accounting*
-r-xr-xr-x  addswap*
-r-xr-xr-x  adjkerntz*

/usr/local/etc/rc.d
Code:
-r-xr-xr-x  avahi-daemon*
-r-xr-xr-x  avahi-dnsconfd*
-r-xr-xr-x  bandwidthd*
-rwxr-xr-x  bastille*
-rwxr-xr-x  cups_browsed*
-rwxr-xr-x  cupsd*
 

mer

Aspiring Daemon

Reaction score: 326
Messages: 540

I think another question qould be:
How are you trying to run it?
If from a Desktop Environment somehow (not a term window or console or regular $SHELL), does it try to associate
a file extension with a "how to run"?

In general, T-Daemon is correct, just need to have execute bit set. Don't forget you can set it for owner, group, other.
It's also common to put the correct shebang as the first line to force the use of a specific shell.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

It is actually more confusing. I tried it and it didn't work.

I put the file "nginx" and set the permissions to "555" into /etc/rc.d, rebooted, and it didn't work. Then, I placed the same file into /usr/local/etc/rc.d, rebooted, it didn't work as well. After that, I renamed it to "nginx.sh" and left it in /usr/local/etc/rc.d and rebooted, and it worked.

Further strangeness: if the filename is "nginx.sh" and I execute the command "# service nginx start", it won't work. I have to change it back to without extention "nginx" in order to execute said command.

Conclusion:
- to make it execute when it bootup, it has to be with .sh extension
- to execute it by "# service <name> start", it has to be without .sh extension.

Would appreciate if someone could clarify...
 

mer

Aspiring Daemon

Reaction score: 326
Messages: 540

where did this file come from? Was it part of a port or a package? If so, the install should put at least a almost runnable sample somewhere.
Can you post the file for us to look at?
At bootup, is there something actually trying to call it with the extension?

The fact that "service" doesn't start it, implies to me that it's not a proper rc init file.
 

T-Daemon

Daemon

Reaction score: 871
Messages: 1,747

I put the file "nginx" and set the permissions to "555" into /etc/rc.d, rebooted, and it didn't work. Then, I placed the same file into /usr/local/etc/rc.d, rebooted, it didn't work as well. After that, I renamed it to "nginx.sh" and left it in /usr/local/etc/rc.d and rebooted, and it worked.
There is this excerpt from rc(8):

Code:
The following key points apply to old-style scripts in
     /usr/local/etc/rc.d/:

     •   Scripts are only executed if their basename(1) matches the shell
         globbing pattern *.sh, and they are executable.  Any other files or
         directories present within the directory are silently ignored.

Further strangeness: if the filename is "nginx.sh" and I execute the command "# service nginx start", it won't work.
That can't work. There is no 'nginx' named file but a 'nginx.sh' named file. Execute service nginx.sh start.

I suspect this has nothing to do with permission settings or file extensions but with the 'nginx' script itself. It would be best to have a look at it, please put it in your next post as mer suggested.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

where did this file come from?
That is a long script and the machine is not Internet connected. I'll do this next time. (I'm doing testing on that machine)

In the meantime,
Code:
The following key points apply to old-style scripts in
     /usr/local/etc/rc.d/:

     •   Scripts are only executed if their basename(1) matches the shell
         globbing pattern *.sh, and they are executable.  Any other files or
         directories present within the directory are silently ignored.
the above tells me something and I think they have to be .sh file extension. I wonder what is the difference between old-style and new-style. Anything doc to read up on this or any info?
 

mer

Aspiring Daemon

Reaction score: 326
Messages: 540

I still stand by
Where did the script come from?
How is it getting called at boot?
 

T-Daemon

Daemon

Reaction score: 871
Messages: 1,747

... I think they have to be .sh file extension.
A rc(8) script doesn't require a .sh suffix. It that was the case then all other scripts in /usr/local/etc/rc.d would have it too. Also there is no indication in rc(8) for a .sh suffix requirement, only the quoted note .

It's more likely your 'nginx' rc(8) script is faulty.

I wonder what is the difference between old-style and new-style.
Can't help here.
Anything doc to read up on this or any info?
The principal documentation for rc(8) scripts are rc(8), rc.subr(8), rcorder(8) and Practical rc.d scripting in BSD.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

I still stand by
Where did the script come from?
How is it getting called at boot?

nginx is web server and here is the script (wasn't written by me, but took it from the web):
It is in /usr/local/etc/rc.d/nginx.sh - must be .sh otherwise it won't execute when booted.
Code:
#!/bin/sh

# if compiled from sources
# place this file inside /usr/local/etc/rc.d
# point _pidfrefix where nginx holds pid file

. /etc/rc.subr

name="nginx"
rcvar=nginx_enable

start_precmd="nginx_precmd"
restart_precmd="nginx_checkconfig"
reload_precmd="nginx_checkconfig"
configtest_cmd="nginx_checkconfig"
gracefulstop_cmd="nginx_gracefulstop"
upgrade_precmd="nginx_checkconfig"
upgrade_cmd="nginx_upgrade"
command="/usr/local/sbin/nginx"
_pidprefix="/usr/local/nginx/logs"
pidfile="${_pidprefix}/${name}.pid"
_tmpprefix="/var/tmp/nginx"
required_files=/usr/local/nginx/conf/nginx.conf
extra_commands="reload configtest upgrade gracefulstop"

[ -z "$nginx_enable" ]        && nginx_enable="NO"
[ -z "$nginxlimits_enable" ]    && nginxlimits_enable="NO"
[ -z "$nginxlimits_args" ]    && nginxlimits_args="-e -U www"

load_rc_config $name

if [ -n "$2" ]; then
    profile="$2"
    if [ "x${nginx_profiles}" != "x" ]; then
        pidfile="${_pidprefix}/${nginx_pid_prefix}${profile}.pid"
        eval nginx_configfile="\${nginx_${profile}_configfile:-}"
        if [ "x${nginx_configfile}" = "x" ]; then
            echo "You must define a configuration file (nginx_${profile}_configfile)"
            exit 1
        fi
        required_files="${nginx_configfile}"
        eval nginx_enable="\${nginx_${profile}_enable:-${nginx_enable}}"
        eval nginx_flags="\${nginx_${profile}_flags:-${nginx_flags}}"
        eval nginxlimits_enable="\${nginxlimits_${profile}_enable:-${nginxlimits_enable}}"
        eval nginxlimits_args="\${nginxlimits_${profile}_args:-${nginxlimits_args}}"
        nginx_flags="-c ${nginx_configfile} -g \"pid ${pidfile};\" ${nginx_flags}"
    else
        echo "$0: extra argument ignored"
    fi
else
    if [ "x${nginx_profiles}" != "x" -a "x$1" != "x" ]; then
        for profile in ${nginx_profiles}; do
            echo "===> nginx profile: ${profile}"
            /usr/local/etc/rc.d/nginx $1 ${profile}
            retcode="$?"
            if [ "0${retcode}" -ne 0 ]; then
                failed="${profile} (${retcode}) ${failed:-}"
            else
                success="${profile} ${success:-}"
            fi
        done
        exit 0
    fi
fi

# tmpfs(5)
nginx_checktmpdir()
{
    if [ ! -d ${_tmpprefix} ] ; then
        install -d -o www -g www -m 755 ${_tmpprefix}
    fi
}

nginx_checkconfig()
{
    nginx_checktmpdir

    echo "Performing sanity check on nginx configuration:"
    eval ${command} ${nginx_flags} -t
}

nginx_gracefulstop()
{
    echo "Performing a graceful stop:"
    sig_stop="QUIT"
    run_rc_command ${rc_prefix}stop $rc_extra_args || return 1
}

nginx_upgrade()
{
    echo "Upgrading nginx binary:"

    reload_precmd=""
    sig_reload="USR2"
    run_rc_command ${rc_prefix}reload $rc_extra_args || return 1

    sleep 1

    echo "Stopping old binary:"

    sig_reload="QUIT"
    pidfile="$pidfile.oldbin"
    run_rc_command ${rc_prefix}reload $rc_extra_args || return 1
}

nginx_precmd()
{
    nginx_checkconfig

    if checkyesno nginxlimits_enable
    then
        eval `/usr/bin/limits ${nginxlimits_args}` 2>/dev/null
    else
        return 0
    fi
}

run_rc_command "$1"

It is called by placing nginx_enable="YES" in /etc/rc.conf.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

Another of my script which I wrote myself:

Code:
#!/bin/sh

. /etc/rc.subr

name=rustapps
rcvar=rustapps_enable

start_cmd="${name}_start"
stop_cmd=":"

load_rc_config $name
: ${rustapps_enable:=no}
: ${rustapps_msg="Nothing started."}

rustapps_start()
{
    sleep 10
    rm /var/log/reader.log
    rm /var/log/processor.log
    rm /var/log/generator.log
    sleep 5
    /usr/local/rustapps/everi.news_server/target/release/reader > /var/log/reader.log &
    sleep 5
    /usr/local/rustapps/everi.news_server/target/release/processor > /var/log/processor.log &
    sleep 5
    /usr/local/rustapps/everi.news_server/target/release/generator > /var/log/generator.log &
}

run_rc_command "$1"

It is called by placing rustapps_enable="YES" in /etc/rc.conf.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,268
Messages: 38,773

nginx is web server and here is the script (wasn't written by me, but took it from the web):
If you install www/nginx it already places a proper /usr/local/etc/rc.d/nginx script. There is no reason to replace it with something else.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

If you install www/nginx it already places a proper /usr/local/etc/rc.d/nginx script. There is no reason to replace it with something else.
Yes, that file is the same file if installed by "pkg install nginx". However, that won't work for me because I had to build some custom modules. So, I had to manually download the source code for nginx and pcre, build it, and then just use that "nginx" script file and set the /usr/local/etc/rc.d/ to run it.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,268
Messages: 38,773

However, that won't work for me because I had to build some custom modules.
The port has a bunch of modules, some of them are not enabled by default so the package doesn't have them. Build it from ports, enable the modules you need and work with that.

So, I had to manually download the source code for nginx and pcre, build it
Don't do that. Everything you install that way isn't registered in the package database. So you won't be able to keep track of it.
 
OP
I

ikevin8me

Active Member

Reaction score: 12
Messages: 198

I posted two scripts above. Let's focus on the rustapps.sh script since I wrote that myself. Can anyone point out why I have to the .sh file extension so that it would run?
 
Top