Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash
On Fri 23-05-14 06:13:13, Eric Blake wrote: > On 05/23/2014 02:32 AM, Libor Pechacek wrote: > > > +++ b/general.c > > @@ -699,7 +699,10 @@ polite_directory_format (name) > >int l; > > > >home = get_string_value ("HOME"); > > - l = home ? strlen (home) : 0; > > + > > + /* remove trailing slashes from $HOME before comparisons */ > > + for (l = home ? strlen (home) : 0; l > 1 && home[l-1] == '/'; l--); > > + > > Does this still work correctly on systems where / and // are distinct > (as allowed by POSIX) and someone has set $HOME to //? Good question. The trimming should not be applied to paths shorter than two characters. As part of the testing, I've found another bug. Updated patch attached. This is how Bash behaves without the patch: bash-master-4.3$ cd bash-master-4.3$ PS1='\w | \W \$ ' ~ | ~ $ HOME=/home /home.local/lpechacek | lpechacek $ cd ~ | ~ $ HOME=/home/ /home | home $ cd /home | home $ HOME=//home /home | home $ cd ~ | ~ $ HOME=//home/ //home | home $ cd //home | home $ HOME=/ //home | home $ cd / | / $ HOME=// / | / $ cd ~ | ~ $ exit and this is behavior with the patch: bash-4.3$ cd bash-4.3$ PS1='\w | \W \$ ' ~ | ~ $ HOME=/home /home.local/lpechacek | lpechacek $ cd ~ | ~ $ HOME=/home/ ~ | ~ $ cd ~ | ~ $ HOME=//home /home | home $ cd ~ | ~ $ HOME=//home/ ~ | ~ $ cd ~ | ~ $ HOME=/ //home | home $ cd / | / $ HOME=// / | / $ cd ~ | ~ $ exit >From ef9c5e823131098d90b3f2aabaf539df59a01cba Mon Sep 17 00:00:00 2001 From: Libor Pechacek Date: Fri, 23 May 2014 09:30:49 +0200 Subject: [PATCH] Make \w and \W tolerate trailing slash in $HOME Currently \w and \W abbreviate $HOME into tilde only when it ends with a character different from slash. This patch makes them tolerate trailing slashes. --- general.c | 5 - parse.y | 10 -- y.tab.c | 10 -- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/general.c b/general.c index 087689eb74cc..02163d3079c3 100644 --- a/general.c +++ b/general.c @@ -699,7 +699,10 @@ polite_directory_format (name) int l; home = get_string_value ("HOME"); - l = home ? strlen (home) : 0; + + /* remove trailing slashes from $HOME before comparisons */ + for (l = home ? strlen (home) : 0; l > 2 && home[l-1] == '/'; l--); + if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/')) { strncpy (tdir + 1, name + l, sizeof(tdir) - 2); diff --git a/parse.y b/parse.y index 91bf3bf649bd..91fbaaa924de 100644 --- a/parse.y +++ b/parse.y @@ -5384,7 +5384,7 @@ decode_prompt_string (string) { /* Use the value of PWD because it is much more efficient. */ char t_string[PATH_MAX]; - int tlen; + int tlen, l; temp = get_string_value ("PWD"); @@ -5415,7 +5415,13 @@ decode_prompt_string (string) #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) /* Abbreviate \W as ~ if $PWD == $HOME */ - if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0)) + /* remove trailing slashes from $HOME before comparisons */ + t = get_string_value ("HOME"); + for (l = t ? strlen (t) : 0; l > 2 && t[l-1] == '/'; l--); + if (l) + t[l] = 0; + + if (c == 'W' && ((t == 0) || STREQ (t, t_string) == 0)) { if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) { diff --git a/y.tab.c b/y.tab.c index 80fe9308398e..d9bf6b1d056a 100644 --- a/y.tab.c +++ b/y.tab.c @@ -7696,7 +7696,7 @@ decode_prompt_string (string) { /* Use the value of PWD because it is much more efficient. */ char t_string[PATH_MAX]; - int tlen; + int tlen, l; temp = get_string_value ("PWD"); @@ -7727,7 +7727,13 @@ decode_prompt_string (string) #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) /* Abbreviate \W as ~ if $PWD == $HOME */ - if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0)) + /* remove trailing slashes from $HOME before comparisons */ + t = get_string_value ("HOME"); + for (l = t ? strlen (t) : 0; l > 2 && t[l-1] == '/'; l--); + if (l) + t[l] = 0; + + if (c == 'W' && ((t == 0) || STREQ (t, t_string) == 0)) { if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) { -- 1.7.12.4
bug-bash@gnu.org
Version: GNU bash, version 4.2.47(1)-release (x86_64-redhat-linux-gnu) Problem: Manual page does not describe the redirection form "n>&-". The manual page section "Duplicating File Descriptors" is as follows: Duplicating File Descriptors The redirection operator [n]<&word is used to duplicate input file descriptors. If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redirection error occurs. If word evalu‐ ates to -, file descriptor n is closed. If n is not specified, the standard input (file descriptor 0) is used. The operator [n]>&word is used similarly to duplicate output file descriptors. If n is not specified, the standard output (file descriptor 1) is used. If the digits in word do not specify a file descriptor open for output, a re‐ direction error occurs. As a special case, if n is omitted, and word does not expand to one or more digits, the standard output and standard error are redirected as described previously. However, the last paragraph does not describe the form "n>&-" (which does close descriptor n). Perhaps that is implied by "similarly", but it would be better to spell it out: is used similarly to duplicate output file descriptors. If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for output, a redirection error occurs. If word expands to -, file descriptor n is closed. If n is not specified, the standard output (file descriptor 1) is used. As a special case, if n is omitted, and word does not expand to one or more digits, the standard output and standard error are redirected as described previously. In addition, the word "evaluates" in the first paragraph should be "expands". The change to file bash.1 is: --- /home/worley/temp/b02014-05-29 14:56:17.631508858 -0400 +++ /home/worley/temp/b12014-05-29 14:59:00.596458326 -0400 @@ -17,7 +17,7 @@ do not specify a file descriptor open for input, a redirection error occurs. If .I word -evaluates to +expands to .BR \- , file descriptor .I n @@ -31,12 +31,24 @@ [\fIn\fP]\fB>&\fP\fIword\fP .RE .PP -is used similarly to duplicate output file descriptors. If +is used similarly to duplicate output file descriptors. +If +.I word +expands to one or more digits, the file descriptor denoted by .I n -is not specified, the standard output (file descriptor 1) is used. +is made to be a copy of that file descriptor. If the digits in .I word do not specify a file descriptor open for output, a redirection error occurs. +If +.I word +expands to +.BR \- , +file descriptor +.I n +is closed. If +.I n +is not specified, the standard output (file descriptor 1) is used. As a special case, if \fIn\fP is omitted, and \fIword\fP does not expand to one or more digits, the standard output and standard error are redirected as described previously. Dale
bug-bash@gnu.org
> However, the last paragraph does not describe the form "n>&-" (which > does close descriptor n). Perhaps that is implied by "similarly", but > it would be better to spell it out: > >is used similarly to duplicate output file descriptors. If >word expands to one or more digits, the file descriptor denoted >by n is made to be a copy of that file descriptor. If the >digits in word do not specify a file descriptor open for >output, a redirection error occurs. If word expands to -, >file descriptor n is closed. If n is not specified, the >standard output (file descriptor 1) is used. As a special >case, if n is omitted, and word does not expand to one or more >digits, the standard output and standard error are redirected >as described previously. Hmm, I'd recommend to always check the most recent bash version. I don't have the most recent, but I already have this: | Duplicating File Descriptors | The redirection operator | | [n]<&word | | is used to duplicate input file descriptors. If word expands to one or more digits, the file descriptor denoted by n is | made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redi‐ | rection error occurs. If word evaluates to -, file descriptor n is closed. If n is not specified, the standard input | (file descriptor 0) is used. | | The operator | | [n]>&word | | is used similarly to duplicate output file descriptors. If n is not specified, the standard output (file descriptor 1) is | used. If the digits in word do not specify a file descriptor open for output, a redirection error occurs. If word evalu‐ | ates to -, file descriptor n is closed. As a special case, if n is omitted, and word does not expand to one or more digits | or -, the standard output and standard error are redirected as described previously. Note the "If word evaluates to -," in both cases. Also, I wouldn't be that picky on "evaluate" vs "expand", because they can be used interchangeable here.