为什么 bash 不打印 PS1 变量?

Why bash not printing PS1 variable?

我想创建远程 bash(通过 tcp 套接字),我写了这段代码:

// servfd is descriptor  to server socket
int sockfd = accept(servfd,&addr,sizeof(addr));
dup2(sockfd,fileno(stdin));
dup2(sockfd,fileno(stdout));
dup2(sockfd,fileno(stderr));
setenv("PS1","# ",1);
execl("/system/bin/sh","sh",NULL);

并且提示没有打印到套接字,但是当我发送命令等时:'echo test'它正在工作但没有提示打印。

我找到了必须使用的解决方案 /dev/ptmx

再次编辑:我是愚蠢的。问题是 shell 不是交互式的,因为 std(in|out|err) 不再是 ttys。使用

execl("/system/bin/sh", "sh", "-i", "NULL");

// along with the fork dance from below  if you want to continue with the main
// program after this

强制 mksh 进行交互,在这种情况下,它应该每次都向 stderr 打印提示。这也将使 mksh 解释 ~/.mkshrc,其中可能设置了 PS1。如果未在此处设置,您仍然需要导出 PS1,并且 system() 的问题仍然存在。如果设置在那里,

system("sh -i");

旧的,可能已过时的答案部分:

编辑:这里的工作比我最初怀疑的要多一些。 system() 在到达其子 shell 的过程中丢弃环境变量。这与它 运行s(在这种情况下)

execl("/bin/sh", "sh", "-c", "sh", NULL);

(也就是说,运行宁sh -c shexported PS1也可以重现)。我不太清楚为什么 sh -c sh 丢弃 PS1;它不会对其他环境变量执行此操作。

在这种情况下,可以通过使用 forkexec 来模仿 system() 调用而不会产生这种效果,如下面的代码所示。但是,PS1 仍需要 export 编辑才能让子进程看到它。

所以,最有可能的原因是 PS1 没有 exported 并且 system() 丢弃了东西。 运行 这段代码检查并生成 shell 并继承 PS1(如果可用):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  pid_t pid;
  char const *ps1 = getenv("PS1");

  if(ps1 != NULL) {
    puts(ps1);
  } else {
    puts("PS1 is NULL");
  }

  pid = fork();
  if(pid == -1) {
    fputs("fork broke. Aborting.\n", stderr);
    return -1;
  } else if(pid == 0) {
    execl("/bin/sh", "sh", NULL);
  } else {
    wait(NULL);
  }

  puts("Continuing here after the shell exited.");

  return 0;
}

对我来说,如果 PS1 未导出,这将打印 PS1 is NULL 并打开默认 PS1 的 shell,如果我 运行,则保留提示] 在 export PS1.

之后再次出现

export 区分了 shell 变量和环境变量。如果您希望子进程继承一个 shell 变量,请通过 export 将其设置为环境变量。