Bash 诺胡普没有';与双安培(&;)而不是分号(;)一起使用时不起作用

Bash 诺胡普没有';与双安培(&;)而不是分号(;)一起使用时不起作用,bash,nohup,Bash,Nohup,我有一个脚本,它使用ssh登录到远程机器,cd到特定目录,然后启动一个守护进程。原始脚本如下所示: ssh server "cd /tmp/path ; nohup java server 0</dev/null 1>server_stdout 2>server_stderr &" 也就是说,直到服务器停止,SSH命令才会返回。将nohup放在cd前面而不是java前面是不起作用的 有人能帮我修一下吗?你能解释一下为什么这个解决方案不起作用吗?谢谢 编辑:cbuckl

我有一个脚本,它使用
ssh
登录到远程机器,
cd
到特定目录,然后启动一个守护进程。原始脚本如下所示:

ssh server "cd /tmp/path ; nohup java server 0</dev/null 1>server_stdout 2>server_stderr &"
也就是说,直到服务器停止,SSH命令才会返回。将
nohup
放在
cd
前面而不是
java
前面是不起作用的

有人能帮我修一下吗?你能解释一下为什么这个解决方案不起作用吗?谢谢

编辑:cbuckley建议使用
sh-c
,我从中得出:

ssh server "nohup sh -c 'cd /tmp/path && java server 0</dev/null 1>master_stdout 2>master_stderr' 2>/dev/null 1>/dev/null &"
ssh服务器“nohup sh-c'cd/tmp/path&&java服务器0master\u stdout 2>master\u stderr'2>/dev/null 1>/dev/null&”
但是,现在当
cd
失败时,退出代码总是
0
;然而,如果我做了
ssh服务器cd/failed/path
,那么我会得到一个真正的退出代码。建议?

ssh服务器“test-d/tmp/path”和&ssh服务器“nohup…&”

回答综述:

  • 错误:使用
    sh-c
    包装整个
    nohup
    命令对我来说不起作用,因为它不会返回错误代码。(@cbuckley)
  • 好的:
    ssh&&ssh
    可以工作,但速度要慢得多(@joachim-nilsson)
  • 好:在
    上创建一个shell脚本,该脚本连续运行命令并返回正确的错误代码
最后一个是我最终使用的。如果理解shell内部结构的人能向我解释,我仍然有兴趣了解为什么原始用例不起作用

&
被附加到整个语句,因为它的优先级高于
&
。您不需要
ssh
来验证这一点。只需在shell中运行此命令:

$ sleep 100 && echo yay &
[1] 19934
如果
&
仅连接到
echo yay
,则shell将休眠100秒,然后报告后台作业。但是,整个
sleep 100&&echo yay
是后台的,您会立即收到作业通知。运行
作业
将显示它挂起:

$ sleep 100 && echo yay &
[1] 20124
$ jobs
[1]+  Running                 sleep 100 && echo yay &
您可以使用括号在
echo yay&
周围创建一个子shell,提供您所期望的:

sleep 100 && ( echo yay & )
这类似于使用
bash-c
运行
echo-yay&

sleep 100 && bash -c "echo yay &"
将这些内容转换为
ssh
,我们可以得到:

# using parenthesis...
$ ssh localhost "cd / && (nohup sleep 100 >/dev/null </dev/null &)"
$ ps -ef | grep sleep
me 20136     1  0 16:48 ?        00:00:00 sleep 100

# and using `bash -c`
$ ssh localhost "cd / && bash -c 'nohup sleep 100 >/dev/null </dev/null &'"
$ ps -ef | grep sleep
me 20145     1  0 16:48 ?        00:00:00 sleep 100

你可以在整个表达中使用
nohup
:谢谢!我想我不能接受任何评论。这看起来仍然是不必要的丑陋,我不知道为什么
&&
会破坏东西。而且,使用
sh-c
我不会在
cd
失败时得到错误代码。那么
ssh服务器“mkdir/tmp/path 2>/dev/null;nohup java…”怎么样。如果目录不存在,则会尝试创建目录,如果目录不存在,则会失败,但是
mkdir
的失败将被忽略。还有一种情况是,
/tmp/path
不存在,但是
mkdir
也会失败,因为它没有创建它的权限,但只要你真的在处理
/tmp/…
,情况就不应该如此,我的问题中需要澄清的另一点是,
cd
错误是当用户运行错误的命令时。。。所以我们不想创建目录。谢谢你!如果只想覆盖优先级,可以使用
{cmd;}
而不是创建子shell。
# using parenthesis...
$ ssh localhost "cd / && (nohup sleep 100 >/dev/null </dev/null &)"
$ ps -ef | grep sleep
me 20136     1  0 16:48 ?        00:00:00 sleep 100

# and using `bash -c`
$ ssh localhost "cd / && bash -c 'nohup sleep 100 >/dev/null </dev/null &'"
$ ps -ef | grep sleep
me 20145     1  0 16:48 ?        00:00:00 sleep 100
ssh server "cd /tmp/path && (nohup java server 0</dev/null 1>server_stdout 2>server_stderr &)"
ssh server "cd /tmp/path && bash -c 'nohup java server 0</dev/null 1>server_stdout 2>server_stderr &'"
$ bash -c "true ; exit 1"
$ echo $?
1
$ bash -c "false ; exit 22"
$ echo $?
22