Reputation: 2614
I'm running a command on my client which sends information to my server:
bin/script.sh ack --id=10 --reason="This is the reason I ack"
This sends a message to a server but for the reason field, it fills in:
reason = "This
I've tried to escape the space (and the quote):
--reason=\"This\ is..."
But I still can't escape the space. The above gets recorded :
reason = "This
Inside of script.sh
there is a line:
#!/bin/sh
RUNDIR=`dirname $0`/..
HQAPILOGDIR=$RUNDIR/logs
CLASSPATH=$CLASSPATH:$RUNDIR/conf
for h in `ls $RUNDIR/*.jar`; do
CLASSPATH=$CLASSPATH:$h
done
for i in `ls $RUNDIR/lib/*.jar`; do
CLASSPATH=$CLASSPATH:$i
done
java -Dhqapi.logDir=$HQAPILOGDIR -cp $CLASSPATH org.hyperic.hq.hqapi1.tools.Shell "$@"
From what I understand, the $@
symbol brings in the arguments from the command line so I'm guessing that this is where my problem is. Is there a way to escape the spaces in my command line arguments? Is the $@ where my problem is occurring?
Upvotes: 1
Views: 325
Reputation: 295443
"$@"
does keep arguments together, without putting them through string-splitting.
You can trivially test this yourself:
#!/bin/sh
printf '%s\n' "$@"
Each argument will be printed on its own line, even if that argument contains spaces.
By the way -- don't escape the quotes! If you write \"This
, then the quote is treated as data, which makes it no longer syntax, which means it no longer functions as a quote at all.
Here's a fully cleaned-up copy of your script:
#!/bin/sh
# these aren't environment variables and should be lower-case
rundir=$(dirname "$0")/..
hqapilogdir=$rundir/logs
for h in "$rundir/conf" "$rundir/"*.jar "$rundir/lib/"*.jar; do
[ -e "$h" ] && CLASSPATH=$CLASSPATH:$h
done
# trim any leading colon from the generated CLASSPATH
CLASSPATH=${CLASSPATH#:}
exec java \
-Dhqapi.logDir="$hqapilogdir" \
-cp "$CLASSPATH" \
org.hyperic.hq.hqapi1.tools.Shell "$@"
If arguments are still parsed incorrectly, the problem is inside the Java code being invoked, not the shell wrapping it. You can verify this by running your script with sh -x scriptname ack --id=10 --reason="This is the reason I ack"
, and watching the commands invoked below.
Upvotes: 3