【问题标题】:How can I change bash directory from C++ program?如何从 C++ 程序更改 bash 目录?
【发布时间】:2019-04-13 03:43:30
【问题描述】:

我有一个 C++ 程序,它最终根据用户输入的索引打印目录路径。

#include <iostream>
using std::cout;
using std::cin;

int main() {

    //SUB-ROUTINE: print directory paths with index, using "complex" algorithm
    //                (so an external command rather than a bash function)
    //                (this sub-routine gives choose-able options to a user)
    //                (please note this sub-routine includes `cout`)

    unsigned index;
    cout << "Input index: ";
    cin >> index;

    switch (index) {
        case 0:
            cout << "/home/user/foo"; break;
        case 1:
            cout << "/home/user/bar"; break;
        default:
            cout << "/home/user";
    }

}

但是你不能用 bash 写

cd $(a.out)

因为很多原因。原因之一是a.out 的输出不仅仅是结果目录路径。

在这种情况下,如何更改调用进程的当前目录(bash)? Linux特定的方式是可以的。当然,将目录路径输出到文件(在 ramdisk 中)并从 bash 中读取它可以实现我想要的,但我认为这不是一个明智的方法。


相关:Changing the directory of the shell through a C++ program


补充:

如果我将 C++ 程序重写为

#include <iostream>
using std::cout;
using std::cin;

int main(int argc, char **argv) {

    if (argc == 1) {

        //print directory paths with index

    } else {

        unsigned index = atoi(argv[1]);

        switch (index) {
            case 0:
                cout << "/home/user/foo"; break;
            case 1:
                cout << "/home/user/bar"; break;
            default:
                cout << "/home/user";
        }

    }

}

,那我就可以写了

./a.out
reply -p "Input index: "
cd $(a.out $REPLY)

但这并不简单(脏)并且使程序更加复杂。

【问题讨论】:

    标签: c++ bash


    【解决方案1】:

    选项 1

    它有点重,但你可以使用

    cd $(a.out | awk '{print $NF}')
    

    选项 2

    换行

    cout << "Input index: ";
    

    cout << "Input index: \n";
    

    然后使用

    cd $(a.out | tail -1)
    

    选项 3

    删除线

    cout << "Input index: ";
    

    一并使用:

    cd $(a.out)
    

    选项 4

    使用一些不同的标记打印所选目录并使用它来过滤输出。

    例子:

    std::cout << "==== " << "/home/user/foo" << std::endl;
    break;
    

    然后,在bash,你可以使用:

    cd $(a.out | grep '====' | awk '{print $2}]
    

    【讨论】:

    • 感谢您的友好回答。但请注意我的 C++ 程序 //print directory paths with index 的注释。很抱歉我的意图对你来说不是很清楚,但是这个评论代表了一个子程序。我想要做的是 1. 打印带有索引的目录列表(即为用户提供可选择的选项),2. 让用户输入带有提示的索引,3. 打印与索引对应的目录。即使使用您的解决方案,$(a.out) 也会包含第一步的输出。第一步的伪代码:for (int i = 0; i &lt; length; ++i) { cout &lt;&lt; i &lt;&lt; " " &lt;&lt; dir_list[i] &lt;&lt; "\n"; }
    • @ynn,请参阅更新后的答案。您可以将其用于您在评论中描述的用例。
    • 谢谢。它运行良好,不会滥用cerr。顺便说一句,难道没有更自然的方式可以让 C++ 程序与调用进程交互吗?例如,我不能定义调用shell的shell变量并在程序退出后使用它吗?伪代码:int main() { /* ... */ define_shell_var("cd_target", selected_directory); }./a.out &amp;&amp; cd ${cd_target}
    • @ynn,我不认为你可以。不允许您这样做可能有很多原因。不熟悉的题目给你一个满意的答复。
    • 我明白了。三思而后行,现在如果可以更改 shell 变量的值似乎真的很危险。我对你有义务。
    【解决方案2】:

    我刚刚找到了答案。

    根据man bash

    命令替换

    (截图)

            Bash 通过在子 shell 环境中执行命令并将命令替换替换为命令的标准输出来执行扩展

    所以除了最后一个(using std::cerr;)之外,可以用cerr替换所有cout

    【讨论】:

    • cerr 的使用应保留用于打印错误消息。使用它来打印用户输入提示是对这个想法的滥用。当然,这是我的看法。
    • @RSahu 一般来说,我真的同意你的看法。如果有其他简单的解决方案,我想避免这样的解决方案。
    猜你喜欢
    • 2018-02-21
    • 2011-01-11
    • 2013-04-02
    • 2014-12-31
    • 2015-02-22
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多