# Cannot escape spaces in command_args in RC script



## Michael-O (Sep 28, 2016)

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:


```
#!/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:

```
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:

```
+ 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 (Sep 28, 2016)

Instead of trying to escape the double quotes, did you try single quotes? 


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


----------



## cpm@ (Sep 28, 2016)

One more thing to change: missing curly brackets.

```
load_rc_config $name
```
should be

```
load_rc_config ${name}
```
To read: https://www.freebsd.org/doc/en_US.ISO8859-1/articles/rc-scripting/rcng-dummy.html


----------



## Michael-O (Sep 28, 2016)

SirDice said:


> Instead of trying to escape the double quotes, did you try single quotes?
> 
> 
> ```
> ...



I have changed the last line to:

```
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:

```
+ 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.


----------



## Michael-O (Sep 28, 2016)

cpm@ said:


> One more thing to change: missing curly brackets.
> 
> ```
> load_rc_config $name
> ...



Thanks for the tip but that article does not use braces and `rclint` does not complain either. Though, I will change it.


----------



## cpm@ (Sep 29, 2016)

Well, I recommended the article to clarify some points, not just how to be written 

I'll take a look to PR 203074.


----------



## SirDice (Sep 30, 2016)

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:

```
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:

```
+ _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:

```
wrapper.displayname=Nexus\ Repository\ Manager\ OSS
```


----------



## Michael-O (Sep 30, 2016)

SirDice said:


> You could try escaping the spaces instead of quoting the argument:
> 
> ```
> 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.


----------



## Michael-O (Sep 30, 2016)

cpm@ said:


> Well, I recommended the article to clarify some points, not just how to be written
> 
> I'll take a look to PR 203074.



Thanks a lot, looking forward to.


----------

