bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

"cd -" is not the same as "cd $OLDPWD"


From: Dustin Boyd
Subject: "cd -" is not the same as "cd $OLDPWD"
Date: Sat, 1 Jul 2023 15:02:52 -0500

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: freebsd13.2
Compiler: cc
Compilation CFLAGS: -g -O2
uname output: FreeBSD localhost 13.2-RELEASE-p1 FreeBSD 13.2-RELEASE-p1 GENERIC 
amd64
Machine Type: x86_64-unknown-freebsd13.2

Bash Version: 5.2
Patch Level: 15
Release Status: release

Description:
        Setting OLDPWD to anything other than an absolute path causes
        `cd -` to behave incorrectly, defaulting to ./$OLDPWD instead of
        being equivalent to `cd $OLDPWD` per POSIX requirements.
        I have tried the following other shells, none of which have this
        bug:

        - ksh93u+m/1.0.6
        - oksh (OpenBSD ksh port)
        - mksh
        - pdksh
        - dash
        - BusyBox (ash)
        - zsh with `setopt POSIX_CD`
        - FreeBSD sh (not a POSIX sh, btw)

Repeat-By:
        $ set -e
        $ mkdir -p /tmp/d1/x/x
        $ CDPATH=/tmp/d1
        $ cd x
        /tmp/d1/x
        $ cd x
        /tmp/d1/x
        $ echo $PWD $OLDPWD
        /tmp/d1/x /tmp/d1/x
        $ OLDPWD=x
        $ cd -    # BUG
        x
        $ pwd     # BUG result
        /tmp/d1/x/x
        $ OLDPWD=x
        $ cd "$OLDPWD"
        /tmp/d1/x

Fix:
        Make `cd -` retrieve the value of `$OLDPWD`, then behave as if
        `cd $OLDPWD` was used with the exception that the new working
        directory is still printed.

        Attached is a sample patch that revises the logic to this:

                if list is null
                        ...
                #ifdef CD_COMPLAINS
                else if list->next
                        ...
                #endif
                else
                        if list->word->word == "-"
                                dirname = $OLDPWD else return EXECUTION_FAILURE
                                lflag = LCD_PRINTPATH
                        else
                                dirname = list->word->word
                        end

                        if !abspath(dirname)    and
                           privileged_mode == 0 and
                           (cdpath = get_string_value("CDPATH"))
                                // if things work with $CDPATH, return early
                        end
                end

                // regular cd without using $CDPATH

Attachment: patch-builtins_cd.def
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]