Austin Group Defect Tracker

Aardvark Mark III

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001045 [1003.1(2013)/Issue7+TC1] Shell and Utilities Editorial Enhancement Request 2016-04-23 15:07 2017-07-06 20:06
Reporter stephane View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Interpretation Required  
Name Stephane Chazelas
User Reference
Section cd utility
Page Number 2529
Line Number 81569
Interp Status Approved
Final Accepted Text Note: 0003749
Summary 0001045: Issues with "cd -"
Description As worded, the description of the "cd" utility implies that

   cd -P -


   cd -L -

(or anything other than "cd -") would do a chdir("-") while in practice in all implementations I've tried "cd -P -" does more or less the same as "cd -P -- "$OLDPWD"" (at least for values of $OLDPWD that start with "/").

Also if $OLDPWD doesn't start with a "/", I find that behaviour varies among shells with no shell following the standard as currently worded.

I could find no shell where "OLDPWD=-P cd -" was the same as "cd -P -P && pwd" as mandated by POSIX. Of course there's the issue of "OLDPWD=- cd -" that would end up being recursive with the current description

For "$OLDPWD" values like "relative-path", I find some implementations honour "$CDPATH", some don't.

The spec says "Consequence of errors: The working directory shall remain unchanged." which contradicts "cd -" being the same as "cd "$OLDPWD" && pwd" as "pwd" could exit with an error (after cd having successfully changed the current directory).


cd - >&-

I find that "bash" and "dash" exit with a non-zero exit status (because of the failure to write the new directory to stdout), but that behaviour is not desirable and I'd rather a non-zero exit status guarantee the current directory has not been changed.

I also find that bash (4.3) ignores $OLDPWD in the environment it receives on startup and ksh93 (u) ignores the $OLDPWD variable passed on the cd command line but IMO that should be considered as bugs in those implementations:

$ OLDPWD=/tmp bash -c 'cd -'
bash: line 0: cd: OLDPWD not set
$ OLDPWD=/tmp ksh -c 'OLDPWD=/bin cd -'
Desired Action Change the wording to have one synopsis:

    cd [-PL] arg

And change the description to note that if "arg" is "-", it should be replaced with the value of "$OLDPWD" with behaviour unspecified when that value doesn't start with "/" and proceed as per the rest of the procedure but note that then, "cd" would output the new value of $PWD followed by a newline character (ignoring any write error) if the chdir() was successful.


In "APPLICATION USAGE", add a section like:

  Because "cd" treats "-" specially, the

    CDPATH= cd -P -- "$dir"

  cannot be used to change to an arbitrary directory. For reliability, an
  application should use something like:

    case $dir in
      (/*) CDPATH= cd -P "$dir";;
      ("") CDPATH= cd -P "";;
      (*) CDPATH= cd -P "./$dir";;

Tags tc3-2008
Attached Files

- Relationships
related to 0001047Resolved Unspecified behaviour for cd "" causes a safety issue 

-  Notes
joerg (reporter)
2016-04-25 10:13

cd "" is not permitted, as NULL path objects are not permitted.
stephane (reporter)
2016-04-25 10:42
edited on: 2016-04-25 10:47

Re: (0003173)

Yes, but "cd ./" is permitted, the

("") CDPATH= cd -P "";;


    case $dir in
      (/*) CDPATH= cd -P "$dir";;
      ("") CDPATH= cd -P "";;
      (*) CDPATH= cd -P "./$dir";;

Is to make sure a "cd ''" is not changed into "cd ./", but passed to chdir() asis so an error be reported for instance.

(Note that the example code also assumes * can match any sequence of bytes since a directory name doesn't have to be made of characters valid in the current locale. It's true with most current sh implementations (yash being the exception) but unclear in the spec. It was discussed on the mailing list some time ago, but the discussion more or less died out)).

geoffclare (manager)
2016-04-25 10:48
edited on: 2016-04-25 11:19

(Response to Note: 0003173)
No, the behaviour of chdir("") is irrelevant, as cd "" is required to do a CDPATH search and the end result is either a chdir() call with a non-empty pathname or a failed search.

Update: the above was based on the numbered steps in the cd description, but I just noticed that the description of the directory operand says "If directory is an empty string, the results are unspecified".

Vincent Lefevre (reporter)
2016-05-12 14:17

I would prefer: if $OLDPWD does not start with a "/", cd shall write a diagnostic message to standard error and exit with non-zero status.

This would be safer than unspecified behavior and I don't think that this would break existing scripts.
geoffclare (manager)
2017-05-25 16:33
edited on: 2017-06-01 15:40

Interpretation response
The standard states that
    cd -
is equivalent to
    cd "$OLDPWD" && pwd
and conforming implementations must conform to this. However, concerns have been raised about this which are being referred to the sponsor.

As written, the standard currently requires odd behavior for cases such as OLDPWD="-P".

Notes to the Editor (not part of this interpretation):
On page 2561 line 82907 section cd, delete:
    cd -
from the SYNOPSIS.

On page 2562 line 82990-82993 section cd, change:
When a <hyphen-minus> is used as the operand, this shall be equivalent to the command:
    cd "$OLDPWD" && pwd
which changes to the previous working directory and then writes its name.
If directory consists of a single '−' (<hyphen-minus>) character, the cd utility shall behave as if directory contained the value of the OLDPWD environment variable, except that after it sets the value of PWD it shall write the new value to standard output. The behavior is unspecified if OLDPWD does not start with a <slash> character.

(note the removal of the − paragraph tag)

On page 2563 line 83018 section cd, change:
A pathname of the previous working directory, used by cd −.
A pathname of the previous working directory, used when the operand is '−'. If an application sets or unsets the value of OLDPWD, the behavior of cd with a '−' operand is unspecified.

On page 2563 line 83024 section cd, change:
or if cd − is used
or if the operand '−' is used

On page 2564 line 83048 section cd, add a new paragraph to APPLICATION USAGE:
Since cd treats the operand '−' as a special case, applications should not pass arbitrary values as the operand. For example, instead of:
    CDPATH= cd -P -- "$dir"
applications should use the following:
    case $dir in
    (/*) CDPATH= cd -P "$dir";;
    ("") CDPATH= cd -P "";;
    (*) CDPATH= cd -P "./$dir";;
(The special treatment of "" is to avoid prefixing it with "./"; an alternative would be to report empty "$dir" as an error to avoid unspecified behavior.)

On page 2565 line 83080 section cd, change FUTURE DIRECTIONS from:
A future version of this standard may require cd to treat an empty directory operand as an error.

ajosey (manager)
2017-06-02 13:34

Interpretation proposed: 2 June 2017
stephane (reporter)
2017-06-10 14:14
edited on: 2017-06-10 17:50

Thanks. The resolution is fine to me.

About the application usage section, I'd just add a note that since a file path can be any array of non-null bytes, the case $dir in /*) is currently not clearly specified in the case where those bytes don't form valid characters (it's not even clear if such arrays of bytes may be stored in shell variables). In any case, that's something that would have to be addressed in a separate issue. But possibly, that means that the example above would have to be amended to have a "LC_ALL=C" read, parsed and run before the "case" command is run.

Also, as noted on the mailing list, we may want to add similar usage sections for the other cases where "-" is a problem (most text utilities and more).

ajosey (manager)
2017-07-06 20:06

Interpretation approved: 6th July 2017

- Issue History
Date Modified Username Field Change
2016-04-23 15:07 stephane New Issue
2016-04-23 15:07 stephane Name => Stephane Chazelas
2016-04-23 15:07 stephane Section => cd utility
2016-04-23 15:07 stephane Page Number => 2529
2016-04-23 15:07 stephane Line Number => 81569
2016-04-25 10:13 joerg Note Added: 0003173
2016-04-25 10:42 stephane Note Added: 0003174
2016-04-25 10:47 stephane Note Edited: 0003174
2016-04-25 10:47 stephane Note Edited: 0003174
2016-04-25 10:48 geoffclare Note Added: 0003175
2016-04-25 10:49 geoffclare Note Edited: 0003175
2016-04-25 11:19 geoffclare Note Edited: 0003175
2016-04-25 11:34 geoffclare Relationship added related to 0001047
2016-05-12 14:17 Vincent Lefevre Note Added: 0003226
2017-05-25 16:33 geoffclare Note Added: 0003749
2017-05-25 16:35 geoffclare Note Edited: 0003749
2017-05-25 16:36 geoffclare Interp Status => Pending
2017-05-25 16:36 geoffclare Final Accepted Text => Note: 0003749
2017-05-25 16:36 geoffclare Status New => Interpretation Required
2017-05-25 16:36 geoffclare Resolution Open => Accepted As Marked
2017-05-25 16:36 geoffclare Tag Attached: tc3-2008
2017-06-01 15:40 geoffclare Note Edited: 0003749
2017-06-01 15:43 Don Cragun Note Added: 0003750
2017-06-01 15:44 Don Cragun Note Deleted: 0003750
2017-06-02 13:34 ajosey Interp Status Pending => Proposed
2017-06-02 13:34 ajosey Note Added: 0003752
2017-06-10 14:14 stephane Note Added: 0003758
2017-06-10 17:50 stephane Note Edited: 0003758
2017-07-06 20:06 ajosey Interp Status Proposed => Approved
2017-07-06 20:06 ajosey Note Added: 0003808

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker