0

Is there any good way i can make some data created by my c++ program available to the shell after exiting the program?

I have a c++ program, inside which i have a string containing a path:

std::string path = "/home/some/path"

I want this path to be available after the c++ program exits main and i am returned to the shell, so that i can use that path (e.g. cd to that path).

I have considered/tried the following approaches:

  • I tried making an environment variable in c++ program using setenv(). However the environment variable only exists while in the c++ program, and it is apparently not possible to make those changes visible in the shell after exiting the program.

  • (considered) writing the path to a temporary file, so that a bash script could later access the details of the path from it. However i have read many suggestions to not do that due to security vulnerabilities.

  • I tried calling the bash script from within the c++ program, using system(). This does not work if i try to cd to that directory (exiting the program will keep me in the same directory as before).

I figure that if i am desperate, i could have my program cout the path, and use the solutions as described here:

$ ./program | tee output.txt

Then the path is stored inside the file. This works technically, but has the undesirable effect of creating a file and printing the path to the screen, and is basically creating a temporary file.

another option to, again, cout in my program, and use command substitution. running in the shell

$ var=$(./program)

storing the path in var. This didnt work because my program does many things including requiring user input before calling

std::cout<< path << std::endl;.

Particularly, i have observed this approach to not display a curses window, which is required for the program. the only solution that has worked is piping the output to tee.

Tak Makoni
  • 467
  • 1
  • 4
  • 7
  • yes that is what i meant thanks! edited. – Tak Makoni Feb 23 '20 at 21:17
  • "shell" is not a programming language or a program, see its tag's description. You may want to tag it with the actual shell you are using. – Ulrich Eckhardt Feb 23 '20 at 21:38
  • You *can* execute things using `system()`. Why and how that failed for you is unclear. Also, your question looks like a so-called "xy problem", so you may be asking the wrong question altogether. – Ulrich Eckhardt Feb 24 '20 at 07:19

2 Answers2

1

Environment variables are only an input, they cannot be used to return any information from a program.

You are already using std::cin and std::cout for user input, and std::cerr should be reserved for error messages. However, you can have the shell open more filedescriptors, and have your program write to those. However, doing this with pure C++ is not possible. But if you don't mind using POSIX C functions:

#include <cstdio>

int main() {
    FILE *f = fdopen(3, "w");
    fprintf(f, "some path\n");
}

And then use it like so:

./program 3> output.txt

This of course creates an undesirable file. I don't think there is any way to store the output from an extra filedescriptor directly to a variable in bash. However, you could create a temporary file inside /dev/shm, so it will never be written to disk, or create a FIFO object and redirect the output from the program to the FIFO, and then read it back. For some examples of how to do this, see this question.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
  • Thanks. if i write to /dev/shm do i need to manually remove the file afterwards? because it using RAM do i need to check if the file is not too large? if so, i would appreciate some further guidance on how to do so properly, thanks again – Tak Makoni Feb 24 '20 at 09:23
  • Yes, you'd have to remove it. The easiest way is to use the trap command to [clean up before bash exits](https://stackoverflow.com/questions/2129923/how-to-run-a-command-before-a-bash-script-exits). – G. Sliepen Feb 24 '20 at 18:54
0

You could write the output that you want the user to see to stderr instead of stdout. Only output what you need your shell script to see to stdout:

#include <iostream>

int main() {
    std::clog << "Enter data: "; // clog prints to stderr like cerr
    std::string line;
    std::getline(std::cin, line);
    std::cout << line << '\n';
}

Then this will work:

var=$(./program)
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108