$HOME does not get abbreviated in prompt \w output when there is a trailing slash
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc -I/home/abuild/rpmbuild/BUILD/bash-4.2 -L/home/abuild/rpmbuild/BUILD/bash-4.2/../readline-6.2 Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-suse-linux-gnu' -DCONF_VENDOR='suse' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -fmessage-length=0 -grecord-gcc-switches -fstack-protector -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables -g -D_GNU_SOURCE -DRECYCLES_PIDS -Wall -g -std=gnu89 -Wuninitialized -Wextra -Wno-unprototyped-calls -Wno-switch-enum -Wno-unused-variable -Wno-unused-parameter -ftree-loop-linear -pipe -DBNC382214=0 -fprofile-use uname output: Linux fmn.suse.cz 3.12.18-4-default #1 SMP Thu May 8 16:21:49 UTC 2014 (607beab) x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-suse-linux-gnu Bash Version: 4.2 Patch Level: 46 Release Status: release Description: Bash prompt always shows full path in prompt instead of tilde abbreviation when $HOME ends with slash. Repeat-By: lpechacek@fmn:~> PS1='\w\$ ' ~$ HOME=/home/lpechacek/ /home/lpechacek$ HOME=/home/lpechacek ~$ # the above line should start with '~$ '
Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash
Hi Chet, On Fri 16-05-14 09:13:34, Chet Ramey wrote: > On 5/16/14, 5:22 AM, Libor Pechacek wrote: > > > Bash Version: 4.2 > > Patch Level: 46 > > Release Status: release > > > > Description: > > Bash prompt always shows full path in prompt instead of tilde > > abbreviation when $HOME ends with slash. > > This came up in March, 2012: > > http://lists.gnu.org/archive/html/bug-bash/2012-03/msg00055.html > > My opinion that this is not a bug in bash hasn't changed. There are a > number of easy ways to remove this trailing slash. Agree. On the other hand, passwd(5) does not fobid the trailing slash. That said I think that either bash should tolerate the trailing slash - will likely be easy as you mentioned above - or the limitation should be documented in bash manual so that no more people burn their time on this unexpected behavior. Libor -- Libor Pechacek Project Manager SUSE Labs, Prague
Re: $HOME does not get abbreviated in prompt \w output when there is a trailing slash
On Fri 16-05-14 09:13:34, Chet Ramey wrote: > On 5/16/14, 5:22 AM, Libor Pechacek wrote: > > > Bash Version: 4.2 > > Patch Level: 46 > > Release Status: release > > > > Description: > > Bash prompt always shows full path in prompt instead of tilde > > abbreviation when $HOME ends with slash. > > This came up in March, 2012: > > http://lists.gnu.org/archive/html/bug-bash/2012-03/msg00055.html > > My opinion that this is not a bug in bash hasn't changed. There are a > number of easy ways to remove this trailing slash. Proposed patch: >From da53c262cb7c356a09e5786f01e6c8c8d7301940 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 | 8 ++-- y.tab.c | 6 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/general.c b/general.c index 087689eb74cc..de6093b57995 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 > 1 && 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..2abfceb1b6ee 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,11 @@ 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 > 1 && t[l-1] == '/'; l--); + + if (c == 'W' && ((t == 0) || STREQN (t, t_string, l) == 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..d107e5b8dec5 100644 --- a/y.tab.c +++ b/y.tab.c @@ -7727,7 +7727,11 @@ 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 > 1 && t[l-1] == '/'; l--); + + if (c == 'W' && ((t == 0) || STREQN (t, t_string, l) == 0)) { if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) { -- 1.7.12.4
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