How does a shell guess the PATH when spawned in an empty environment?

Lets re-write your program as following: #include #include int main(int argc, char **argv, char **envp) { execle("/bin/sh", "sh", "-c", "ls", (char*)NULL, NULL); return 0; } Now, once you compile and run with ltrace, you'll find the following snippet in the output: ) = NULL strlen("ls") = 2 memcpy(0x0061cbe0, "/usr/local/sbin", 15) = 0x0061cbe0 strcpy(0x0061cbf0, "ls") = 0x0061cbf0 __xstat64(1, "/usr/local/sbin/ls", 0x7fffb173e120) = -1 strlen("ls") = 2 memcpy(0x0061cbe0, "/usr/local/bin", 14) = 0x0061cbe0 strcpy(0x0061cbef, "ls") = 0x0061cbef __xstat64(1, "/usr/local/bin/ls", 0x7fffb173e120) = -1 strlen("ls") = 2 memcpy(0x0061cbe0, "/usr/sbin", 9) = 0x0061cbe0 strcpy(0x0061cbea, "ls") = 0x0061cbea __xstat64(1, "/usr/sbin/ls", 0x7fffb173e120) = -1 strlen("ls") = 2 memcpy(0x0061cbe0, "/usr/bin", 8) = 0x0061cbe0 strcpy(0x0061cbe9, "ls") = 0x0061cbe9 __xstat64(1, "/usr/bin/ls", 0x7fffb173e120) = -1 strlen("ls") = 2 memcpy(0x0061cbe0, "/sbin", 5) strcpy(0x0061cbe6, "ls") = 0x0061cbe6 __xstat64(1, "/sbin/ls", 0x7fffb173e120) = -1 strlen("ls") = 2 memcpy(0x0061cbe0, "/bin", 4) = 0x0061cbe0 strcpy(0x0061cbe5, "ls") = 0x0061cbe5 __xstat64(1, "/bin/ls", 0x7fffb173e120) = 0 strlen("ls") = 2 malloc(26) = 0x025fa110 strcpy(0x025fa123, "ls") = 0x025fa123 realloc(NULL, 160) = 0x025fa140 fork() As you can see, it's clearly looking for the right path before doing the fork() with '/bin/ls' which is the right path for 'ls'. If there was $PATH variable given, sh would try those paths to find the location of ls. Since there is no $PATH provided in this case, plausible paths (e.g. /bin, /usr/bin, /sbin) are tried nevertheless.

From execle man-page: If this PATH variable isn't specified, the default path is set according to the _PATH_DEFPATH definition in , which is set to /usr/bin:/bin.

– JB. Oct 2 at 12:48 @JB: The answer is (as the ltrace output points to), since there was no $PATH given, it looks through some plausible paths for the right location of 'ls' until it is found. Once the right path for 'ls' is found, it executes.

The crude answer is: it is programmed to do so. – GSBabil Oct 2 at 12:51.

From the execle man page: On some other systems the default path (used when the environment does not contain the variable PATH) has the current working directory listed after /bin and /usr/bin, as an anti-Trojan-horse measure. Linux uses here the traditional "current directory first" default path. So I guess your default path is .

/:/bin:/usr/bin if on Linux, /bin:/usr/bin otherwise.

Bin/sh sets a lot of variables on its own if they're undefined by the time it starts. You can see the full list easily by running env -i sh -c set For example, on my system: $ env -i sh -c set IFS=' ' OPTIND='1' PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' PPID='2299' PS1='$ ' PS2='> ' PS4='+ ' PWD='/home/jb' Note how this includes PATH. Also note that PATH gets a status of variable only; it does not get promoted to the exported environment.

Cross-check that with env -i sh -c env. $ env -i sh -c env PWD=/home/jb.

However If I set the execle's env to char *env_init = {"USER=unknown", "PATH=\tmp", NULL};, the ls command don't work. – manutd Oct 2 at 13:19 @manutd, yes, they're only set if not already present. Should have said that explicitely, editing... – JB.

Oct 2 at 13:56.

The reason this can work is that POSIX says this about PATH: If PATH is unset or is set to null, the path search is implementation-defined. Your /bin/sh uses a default PATH for this case, which happens to include the directory with the ls executable. On my system (FreeBSD) I can inspect this with $ strings -a /bin/sh | grep /bin: /usr/bin:/bin:/usr/sbin:/sbin PATH=/usr/bin:/bin.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions