Issue
I am trying to get the shell that is being used (where the code is being executed on).
For example if the binary was named tmp
when I execute ./tmp
on a bash shell I get an printf of bash, but if I execute it on a zsh shell I get an printf of zsh
I currently tried
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char command[50];
strcpy( command, "echo $0" );
system(command);
return 0;
}
But the only output I get is sh
which is not my desired output.
Solution
If you are trying to answer the question, "what is the parent of the current command", you'll need to:
- Get the process id of the parent process, and then
- Figure out the command name for that pid
But if you are trying to answer the question, "what shell is configured as the default shell for the current user", that is a different question. I'm assuming you're asking the first question here.
Getting your parent PID is easy; just use the getppid()
function:
pid_t parent_pid;
parent_pid = getppid();
Getting the command associated with that pid is straightforward but requires a few more steps. The simplest solution is probably reading the value from /proc/<pid>/comm
, which means:
- Compute a pathname from the
parent_pid
variable - Open the file
- Read the contents into a buffer
Maybe something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifndef BUFSIZ
#define BUFSIZ 8192
#endif
int main()
{
char path[BUFSIZ], comm[BUFSIZ];
pid_t parent_pid = getppid();
int fd;
// compute the pathname
if (snprintf(path, BUFSIZ, "/proc/%d/comm", parent_pid) > BUFSIZ) {
fprintf(stderr, "path too long\n");
exit(1);
}
// open the file
if (-1 == (fd = open(path, O_RDONLY))) {
fprintf(stderr, "failed to open comm file\n");
exit(1);
}
// read the contents into the `comm` variable
memset(comm, 0, BUFSIZ);
if (-1 == read(fd, comm, BUFSIZ-1)) {
perror("read");
exit(1);
}
printf("launched from: %s\n", comm);
if (-1 == close(fd)) {
perror("close");
exit(1);
}
return 0;
}
Launched from a bash
shell, we see:
bash$ ./getparent
bash
Launched from tclsh
we see:
bash$ tclsh
% ./getparent
launched from: tclsh
Or from Python:
bash$ python
>>> print(subprocess.check_output('./getparent').decode())
launched from: python
So it seems to work as advertised.
Answered By - larsks Answer Checked By - David Marino (WPSolving Volunteer)