On Mon, May 29, 2017 at 06:25:06PM -0400, Chet Ramey wrote: [...] > If PWD appears in the environment, and it is an absolute pathname of the > CWD, set PWD to the canonicalized version of the environment value. The > canonicalized version removes . and .., makes sure that the length is > less than PATH_MAX, and validates that at each step, removing . and .. > results in a valid pathname. If canonicalization fails, PWD gets the value > that would be printed by pwd -P if PWD were not set.
That's not quite true. In variables.c `set_pwd', there's the following: 843 temp_var = find_variable ("PWD"); 844 /* Follow posix rules for importing PWD */ 845 if (temp_var && imported_p (temp_var) && 846 (temp_string = value_cell (temp_var)) && 847 temp_string[0] == '/' && 848 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL)) 849 { 850 current_dir = sh_canonpath (temp_string, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); 851 if (current_dir == 0) 852 current_dir = get_working_directory ("shell_init"); 853 else 854 set_working_directory (current_dir); 855 free (current_dir); 856 } `current_dir' is a copy of `temp_string' which holds the canonicalized version of the environment value. That's true. *But* PWD is not re-set to the value of `current_dir'. Instead, it has the same value as passed through the environment (i.e. `temp_string'). For completeness, in builtins/common.c `set_working_directory' just updates a global variable, but doesn't touch the value of the PWD variable. 589 /* Make NAME our internal idea of the current working directory. */ 590 void 591 set_working_directory (name) 592 char *name; 593 { 594 FREE (the_current_working_directory); 595 the_current_working_directory = savestring (name); 596 } Hence, my initial patch: diff --git a/variables.c b/variables.c index 944de86e..62f9f229 100644 --- a/variables.c +++ b/variables.c @@ -852,6 +852,8 @@ set_pwd () current_dir = get_working_directory ("shell_init"); else set_working_directory (current_dir); + temp_var = bind_variable ("PWD", current_dir); + set_auto_export (temp_var); free (current_dir); } else if (home_string && interactive_shell && login_shell &&