0

I found that this link provides how to add the file name in $PATH but not in c programming language. When I run the codes, it simply prints out the original path instead of the modified path. Interestingly, when I put system("echo $PATH:~/opt/bin"), it successfully show the modified path. Also, I'm not sure how to remove the same file name (~/opt/bin) from the modified path.

My codes are here:

int main (void) {

  system("echo $PATH");
  system("export PATH=$PATH:~/opt/bin");
  system("echo $PATH"); //prints out the original $PATH

}

Unfortunately, getenv or setenv do not modify the path. When I used the following code here,

int main() {
    char *oldenv = strdup(getenv("PATH")); // Make a copy of your PATH
    setenv("PATH", "$PATH:~/opt/bin", 1); // Overwrite it

    system("echo $PATH"); // Outputs "$PATH:~/opt/bin"

    setenv("PATH", oldenv, 1); // Restore old PATH
    free(oldenv); // Don't forget to free!

    system("echo $PATH"); // Outputs your actual PATH
}

the codes prints out the hard-coded $PATH:~/opt/bin instead of the usual $PATH command.

  • 2
    That is because ```$PATH``` is interpreted by shell but not by ```setenv```. If you want to change the ```PATH``` in C, you should do string concatenation with something like ```strncat``` – clpgr Apr 15 '20 at 01:54
  • Thank you! I will use `strncat` to add the filename. May I ask how I can remove a filename from the path also? –  Apr 15 '20 at 01:57
  • May I actually ask one more question? I constantly fail to save `$PATH` to a variable. I used `path = system($PATH)` and `path = execl("/bin/sh", "sh", "-c", "echo $PATH", NULL);` but both did not work. How may I do this? –  Apr 15 '20 at 02:02
  • 1
    Do what you usually do to manipulate string in C. This question can be generalized to how to remove a substring from a string. Maybe this link https://stackoverflow.com/a/47117431/13266768 can help you. – clpgr Apr 15 '20 at 02:02
  • That makes sense. Thank you for your explanation and time. –  Apr 15 '20 at 02:05
  • ```system``` and ```execl``` does not return the stdout of the command. They both return int. Check the documentation with ```man system``` and ```man execl```. Isn't ```getenv``` serve your purpose well? – clpgr Apr 15 '20 at 02:10
  • Thank you very much for your comment. I found that `getenv` accepts a pointer so I set a char pointer to save the path. Somehow, when I tried to print out, there was a warning sign states that `format not a string literal and no format arguments`, but it worked. –  Apr 15 '20 at 02:18
  • You're welcome. Forgive my stupid grammar errors in the previous comment. Haven't learn English properly. You actually should do ```printf("%s\n", path)``` or ```puts(path)```. As the warning said, the first argument of ```printf``` should be a string literal or there should be additional arguments to ```printf```. – clpgr Apr 15 '20 at 03:14
  • We usually pass pointer as the first argument when the format string it points to contains conversion specifiers and there are additional arguments correspond to those specifiers. We can use this format string multiple times to get a consistent format. E.g. to display key-value pairs we can write ```char *fmt = "%s -> %s\n"; printf(fmt, k1, v1); printf(fmt, k2, v2);``` – clpgr Apr 15 '20 at 03:15

1 Answers1

0

Thanks to @clpgr, I could write the following codes to save the result of $PATH in a char string.

int main (void) {

  char* path;
  path = getenv("PATH");
  if (path)
  {
    printf(path);    
  }  
}