问题
I am working on writing a Bash function to start a server that needs to be started from a certain folder, but I don't want starting this server to impact my current work. I've written the following:
function startsrv {
pushd .
cd ${TRUNK}
${SERVERCOMMAND} &
popd
}
My variables are all set, but when this executes, I get an error regarding an unexpected semicolon in the output, it appears that Bash is inserting a semicolon after the ampersand starting ${SERVERCOMMAND}
in the background.
Is there anything I can do to start ${SERVERCOMMAND}
in the background while still using pushd and popd to make sure I end up back in my current directory?
Edit: Output of echo ${SERVERCOMMAND}
, since it was requested:
yeti --server --port 8727
Error message:
-bash: syntax error near unexpected token `;'
回答1:
What is the value of $SERVERCOMMAND
? You must have a semi-colon in it.
For what it's worth you can simplify the pushd/cd to one pushd:
pushd $TRUNK
$SERVERCOMMAND &
popd
Or create a subshell so the cd only affects the one command:
(cd $TRUNK; $SERVERCOMMAND &)
回答2:
You can also use cd -
cd $TRUNK
$SERVERCOMMAND &
cd -
回答3:
A semicolon in ${SERVERCOMMAND}
should not trigger a syntax error unless there is a bug in bash
itself. The semicolon problem must be located elsewhere, in a part of the code we don't see.
Aside from the semicolon issue, there are some minor bugs in your code:
- The
${TRUNK}
variable expansion isn't quoted. If the directory name contains whitespace,bash
will split it into multiple fields before invokingcd
. - The return value of
cd ${TRUNK}
isn't checked. If the directory doesn't exist,bash
will invoke the server in the current directory. - The function doesn't test whether
${SERVERCOMMAND}
might fail to execute (e.g., command not found). - The
function
keyword and thepushd
andpopd
commands arebash
-specific, so this code won't run in a POSIX shell.
Here's a safer, POSIX-compatible rewrite:
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
startsrv() {
(
cd "${TRUNK}" || fatal "failed to cd to '${TRUNK}'"
set -- ${SERVERCOMMAND}
command -v "$1" >/dev/null || fatal "command '$1' not found"
command "$@" &
) || exit 1
}
来源:https://stackoverflow.com/questions/6298623/spawn-a-background-process-in-a-bash-function