Cannot escape spaces in command_args in RC script

Hi folks,

I am trying to create a port where command_args receives a value with spaces through %%VAL%%. After looking up the process in htop or ps, I see that the value is truncated, hence not properly escaped by rc.subr.

Here is my RC script:

Code:
#!/bin/sh

# $FreeBSD$
#
# PROVIDE: nexus2
# REQUIRE: LOGIN FILESYSTEMS
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf[.local] to enable Nexus:
#
#  nexus2_enable="YES"

. /etc/rc.subr

name=nexus2
desc="Maven (and others) artifacts repostory manager"
rcvar=nexus2_enable

load_rc_config $name

nexus2_enable="${nexus2_enable:-"NO"}"
nexus2_user=nexus
nexus2_group=nexus

extra_commands=dump

pidfile="/var/run/nexus2/nexus2.pid"

command=/usr/local/lib/javaservicewrapper/bin/wrapper
command_args="/usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2 \
  wrapper.pidfile=${pidfile} wrapper.lockfile=/var/run/nexus2/nexus2.lock \
  wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE \
  wrapper.name=nexus2 wrapper.displayname=\"Nexus Repository Manager OSS\""

run_rc_command "$1"

ps output:
Code:
  PID TT  STAT    TIME COMMAND
15114  -  S    0:00,44 /usr/local/lib/javaservicewrapper/bin/wrapper /usr/local/etc/nexus2/wrapper.conf
wrapper.syslog.ident=nexus2 wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock
wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE
wrapper.name=nexus2 wrapper.displayname=Nexus

Tracing the start is here:
Code:
+ echo 'Starting nexus2.'
Starting nexus2.
+ [ -n '' ]
+ _doit='/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS"'
+ [ -n nexus ]
+ _doit='su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS""'\'
+ [ -n '' ]
+ [ -n '' ]
+ _run_rc_doit 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS""'\'
+ debug 'run_rc_command: doit: su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS""'\'
+ eval 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS""'\'
+ su -m nexus -c 'sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname="Nexus Repository Manager OSS""'
wrapper  | Spawning intermediate process...
+ _return=0
+ [ 0 -ne 0 ]
+ return 0
+ _run_rc_postcmd
+ [ -n '' ]
+ return 0
+ return 0

Is this a limitation in rc.subr? I am quite certain that my escaping is sufficient.

Ideas would be helpful.
 

SirDice

Administrator
Staff member
Administrator
Moderator
Instead of trying to escape the double quotes, did you try single quotes?

Code:
wrapper.displayname='Nexus Repository Manager OSS'
There's no real need for double quotes there anyway.
 
Instead of trying to escape the double quotes, did you try single quotes?

Code:
wrapper.displayname='Nexus Repository Manager OSS'
There's no real need for double quotes there anyway.

I have changed the last line to:
Code:
command_args="/usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2 \
  wrapper.pidfile=${pidfile} wrapper.lockfile=/var/run/nexus2/nexus2.lock \
  wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE \
  wrapper.name=nexus2 wrapper.displayname='Nexus Repository Manager OSS'"

Now start gives me:
Code:
+ echo 'Starting nexus2.'
Starting nexus2.
+ [ -n '' ]
+ _doit='/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\'
+ [ -n nexus ]
+ _doit='su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ [ -n '' ]
+ [ -n '' ]
+ _run_rc_doit 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ debug 'run_rc_command: doit: su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ eval 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ su -m nexus -c 'sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname=Nexus' Repository Manager 'OSS"'
Überflüssiges ".
+ _return=1
+ [ 1 -ne 0 ]
+ [ -z '' ]
+ return 1
+ warn 'failed to start nexus2'
+ [ -x /usr/bin/logger ]
+ logger '/usr/local/etc/rc.d/nexus2: WARNING: failed to start nexus2'
+ echo '/usr/local/etc/rc.d/nexus2: WARNING: failed to start nexus2'
/usr/local/etc/rc.d/nexus2: WARNING: failed to start nexus2
+ return 1

Nested quotes are troublesome here.
 

SirDice

Administrator
Staff member
Administrator
Moderator
The shell treats $myvar and ${myvar} the same so it shouldn't cause any problems. Both are syntactically correct. But in the interest of consistency ${myvar} is preferred. It also helps avoid things like this:
Code:
echo $myvaris something
echo ${myvar}is something
The first line would use the variable $myvaris which is most likely not set and could cause weird errors.

But back to the original issue, looking at the output there's a lot of quoting in the end:
Code:
+ _run_rc_doit 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ debug 'run_rc_command: doit: su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'
+ eval 'su -m nexus -c '\''sh -c "/usr/local/lib/javaservicewrapper/bin/wrapper  /usr/local/etc/nexus2/wrapper.conf wrapper.syslog.ident=nexus2   wrapper.pidfile=/var/run/nexus2/nexus2.pid wrapper.lockfile=/var/run/nexus2/nexus2.lock   wrapper.java.pidfile=/var/run/nexus2/nexus2.java.pid wrapper.daemonize=TRUE   wrapper.name=nexus2 wrapper.displayname='\''Nexus Repository Manager OSS'\''"'\'

You could try escaping the spaces instead of quoting the argument:
Code:
wrapper.displayname=Nexus\ Repository\ Manager\ OSS
 
You could try escaping the spaces instead of quoting the argument:
Code:
wrapper.displayname=Nexus\ Repository\ Manager\ OSS

This is actually what I did. I have removed the variable substitution and added the literal with backslash escapes. Though, this is a mere workaround since this could happen to every variable and since I quote a string, I expect it to be passed correctly to the command by rc.subr.
 
Top