在 bash 函数中生成后台进程

发布于 2024-11-14 15:10:02 字数 593 浏览 3 评论 0原文

我正在编写一个 Bash 函数来启动需要从某个文件夹启动的服务器,但我不希望启动该服务器影响我当前的工作。我编写了以下内容:

function startsrv {
        pushd .
        cd ${TRUNK}
        ${SERVERCOMMAND} & 
        popd
}

我的变量已全部设置,但是当执行时,我收到有关输出中意外分号的错误,看来 Bash 在与号后面插入了一个分号,以 ${SERVERCOMMAND}< /code> 在后台。

我可以做些什么来在后台启动 ${SERVERCOMMAND} 同时仍然使用 Pushd 和 Popd 以确保我最终回到当前目录?

编辑: echo ${SERVERCOMMAND} 的输出,因为已请求:

yeti --server --port 8727

错误消息:

-bash: syntax error near unexpected token `;'

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 `;'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

顾铮苏瑾 2024-11-21 15:10:02

$SERVERCOMMAND 的值是多少?其中必须有分号。

值得一提的是,您可以将 Pushd/cd 简化为一个 Pushd:

pushd $TRUNK
$SERVERCOMMAND &
popd

或者创建一个子 shell,以便 cd 只影响一个命令:

(cd $TRUNK; $SERVERCOMMAND &)

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 &)
揽月 2024-11-21 15:10:02

您还可以使用cd-

cd $TRUNK
$SERVERCOMMAND &
cd -

You can also use cd -

cd $TRUNK
$SERVERCOMMAND &
cd -
迷乱花海 2024-11-21 15:10:02

${SERVERCOMMAND} 中的分号不应触发语法错误,除非 bash 本身存在错误。分号问题一定位于其他地方,位于我们看不到的代码部分。

除了分号问题之外,您的代码中还存在一些小错误:

  • ${TRUNK} 变量扩展未加引号。如果目录名称包含空格,bash 会在调用 cd 之前将其拆分为多个字段。
  • 不检查 cd ${TRUNK} 的返回值。如果该目录不存在,bash 将调用当前目录中的服务器。
  • 该函数不会测试${SERVERCOMMAND}是否可能无法执行(例如,未找到命令)。
  • function 关键字以及 pushdpopd 命令是 bash 特定的,因此此代码不会在POSIX shell。

这是一个更安全、兼容 POSIX 的重写:

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
}

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 invoking cd.
  • 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 the pushd and popd commands are bash-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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文