std::system 使用哪个 shell?

6

TL;DR; 我猜 std::system 使用的 shell 是 sh,但我不确定。

我尝试使用这段代码打印 shell:std::system("echo $SHELL"),输出结果是/bin/bash,这对我来说很奇怪。所以,我想知道如果在 sh 中执行会发生什么?同样的输出:/bin/bash。另外,如果我使用类似 SHELL="/usr/bin/something" 的命令将 SHELL 变量设置为另一个字符串,它将打印出我设置的新字符串(/usr/bin/something),看起来这不是一个好方法来查看正在使用的 shell。因此,我尝试使用 ps 命令进行检查,输出结果是:basha.outps。在这个列表中看到 bash 很奇怪。所以,我创建了一个自定义的 shell,并将 gnome-terminal 中的 shell 更改为它:

#include <iostream>

int main()
{
    std::string input;
    while (true)
    {
        std::string command;
        std::getline(std::cin, command);
        std::system(command.c_str());
    }
}

现在,测试更容易了,并且我认为结果更好。

然后,我再次尝试在自定义 shell 中测试 ps 命令,结果是:test_shellps

这又很奇怪了。为什么 shell 不是 shbash 呢?最后我做的测试是: echo $0。结果在自定义 shell 和正常程序中都是 sh

编辑

看起来 /bin/sh 链接到了 /bin/bashll /bin/sh 命令的输出为 /bin/sh -> bash),而实际上,shbash 之间唯一的区别就是文件名,文件内容相同。我还用 diff 命令检查了这些文件的差异:

$ xxd /bin/sh > sh
$ xxd /bin/bash > bash
$ diff sh bash

(+ 是的,$SHELL 并不表示当前正在运行的 shell(在测试时我并不知道这一点,我只是想看看会发生什么))


5
SHELL 被设置为用户的默认(登录) shell,而不是当前正在运行的 shell。 - jordanm
2
如果您想查看执行的shell是什么,或者让程序启动一个长时间运行的程序,然后从终端使用ps找到其父进程,请在strace -f下运行您的程序。 - Useless
@273K 是的,看起来是真的(使用了 ll /bin/sh 命令,输出结果为 /bin/sh -> bash)。但它们似乎也有所不同。我不知道为什么。 - NoIdeaForUsername
Bash在argv [0]中获取被调用的名称,并根据名称sh或bash可能应用不同的设置并启用不同的shell扩展集。这是一种广泛使用的技术,例如grep,egrep,fgrep,vim,evim,vi... - 273K
2
SHELL甚至不一定是用户的默认登录shell。它只是用户可以在其环境中设置的一个值,以通知其他程序他们更喜欢哪个shell。从这个意义上说,它与PAGER或EDITOR没有任何区别。 - William Pursell
显示剩余6条评论
2个回答

1

0
根据cppreference.comstd::system会调用主机环境的命令处理器(例如/bin/shcmd.execommand.com)。
这意味着所使用的shell取决于操作系统。
在任何POSIX操作系统(包括Linux)上,std::system使用的shell是/bin/sh。(尽管正如OP指出的那样,/bin/sh可能是另一个shell的符号链接。)
至于SHELL环境变量,正如评论中指出的那样,该环境变量不能可靠地用于识别正在运行的shell程序。SHELL被POSIX定义为

表示用户首选命令语言解释器的路径名

source

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接