我正在编写一个Bash函数来启动一个需要从某个文件夹启动的服务器,但我不希望启动这个服务器会影响我当前的工作。我写了以下内容:
function startsrv {
pushd .
cd ${TRUNK}
${SERVERCOMMAND} &
popd
}
我的变量都设置好了,但当执行此操作时,我在输出中收到一个关于意外分号的错误,似乎Bash在与号后面插入了一个分号,并在后台启动${SERVERCOMMAND}
。
我能做些什么来在后台启动${SERVERCOMMAND}
,同时仍然使用pushd和popd来确保我最终回到当前目录中吗?
编辑:echo ${SERVERCOMMAND}
的输出,因为它被请求:
yeti --server --port 8727
错误消息:
-bash: syntax error near unexpected token `;'
$SERVERCOMMAND
的值是多少?你必须有一个分号在里面。
值得一提的是,您可以将pushd/cd简化为一个pushd:
pushd $TRUNK
$SERVERCOMMAND &
popd
或者创建一个子shell,使cd只影响一个命令:
(cd $TRUNK; $SERVERCOMMAND &)
您也可以使用cd -
cd $TRUNK
$SERVERCOMMAND &
cd -
${SERVERCOMMAND}
中的分号不应触发语法错误,除非bash
本身存在错误。分号问题必须位于其他地方,在我们看不到的代码部分中。
除了分号问题,您的代码中还有一些小错误:
- 未引用
${TRUNK}
变量展开式。如果目录名包含空白,bash
将在调用cd
之前将其拆分为多个字段 - 未检查
cd ${TRUNK}
的返回值。如果目录不存在,bash
将调用当前目录中的服务器 - 该函数不测试
${SERVERCOMMAND}
是否可能无法执行(例如,找不到命令) function
关键字以及pushd
和popd
命令都是特定于bash
的,因此此代码不会在POSIXshell中运行
这里有一个更安全、兼容POSIX的重写:
log() { printf '%sn' "$*"; }
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
}