codeCompiler77 codeCompiler77 - 4 months ago 13
Linux Question

Ubuntu Bash Script executing a command with spaces

I have a bit of an issue and i've tried several ways to fix this but i can't seem to.

So i have two shell scripts.

background.sh: This runs a given command in the background and redirect's output.

#!/bin/bash

if test -t 1; then
exec 1>/dev/null
fi

if test -t 2; then
exec 2>/dev/null
fi

"$@" &


main.sh: This file simply starts the emulator (genymotion) as a background process.

#!/bin/bash
GENY_DIR="/home/user/Documents/MyScript/watchdog/genymotion"
BK="$GENY_DIR/background.sh"
DEVICE="164e959b-0e15-443f-b1fd-26d101edb4a5"
CMD="$BK player --vm-name $DEVICE"
$CMD


This works fine when i have NO spaces in my directory. However, when i try to do:
GENY_DIR="home/user/Documents/My Script/watchdog/genymotion"


which i have no choice at the moment. I get an error saying that the file or directory cannot be found. I tried to put
"$CMD"
in quote but it didn't work.

You can test this by trying to run anything as a background process, doesn't have to be an emulator.

Any advice or feedback would be appreciated. I also tried to do.

BK="'$BK'"


or

BK="\"$BK\""


or

BK=$( echo "$BK" | sed 's/ /\\ /g' )

Answer

Don't try to store commands in strings. Use arrays instead:

#!/bin/bash
GENY_DIR="$HOME/Documents/My Script/watchdog/genymotion"
BK="$GENY_DIR/background.sh"
DEVICE="164e959b-0e15-443f-b1fd-26d101edb4a5"
CMD=( "$BK" "player" --vm-name "$DEVICE" )
"${CMD[@]}"

Arrays properly preserve your word boundaries, so that one argument with spaces remains one argument with spaces.

Due to the way word splitting works, adding a literal backslash in front of or quotes around the space will not have a useful effect.

Comments