Why does cd print when run in command substitution?

3

2

If I use the 'cd' BASH built-in in a command substitution, it prints extra stuff to stdout, but only when piped to, eg., less.

$ echo `cd .`

# The output is a single newline, appended by echo.


$ echo `cd .` | less
# less displays:
ESC]2;my.hostname.com - tmp/testenv^G
(END) 

What's going on there? This behavior isn't documented in the bash man page for cd. Obviously, running just 'cd' in a command substitution is silly, but something like

NEWDIR=`cd mypath; pwd`

could be useful.

I solved this by instead using

NEWVAR=`cd mypath > /dev/null 2>&1; pwd`

but I still want to know what's going on.

Bash Version: GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) Copyright (C) 2005 Free Software Foundation, Inc.

Distro: Scientific Linux SL release 5.5 (Boron)

reasgt

Posted 2012-08-29T19:39:07.177

Reputation: 153

I cannot replicate the described behaviour. Do you use $CDPATH? It makes cd output the real path. Or have you defined an alias for cd? – choroba – 2012-08-29T19:44:05.700

Run type cd, result should be cd is a shell builtin. Make sure echo \builtin cd .` | less` results in the same. It forces use of the shell builtin command. Cannot repro, bash 3.2.48(1) on OS X. – Daniel Beck – 2012-08-29T19:47:37.633

I think something must have changed since bash 3.2. See this thread: http://lists.gnu.org/archive/html/bug-bash/2007-04/msg00019.html The problem is that POSIX requires printing of the directory when CDPATH was used, even when not interactive. Why this changed in bash 4.x I don't know, but I can't reproduce it there either.

– reasgt – 2012-08-29T19:49:18.673

Use of command circumvents use of the bash builtin, but instead executes the program returned from which cd. – Daniel Beck – 2012-08-29T19:52:49.227

Answers

0

You are seeing the xterm escape sequence ( ESC 2; new-title^G ) to change the window title.

(The following is mostly conjecture.)

When you write output to the terminal, your terminal emulator (I'm guessing) removes it from the stream before displaying it on the screen. When you pipe the output through less, you see all the output.

Check the value of $PROMPT_COMMAND; you might see a command there that prints the string (likely involving $PWD or a call to pwd).

chepner

Posted 2012-08-29T19:39:07.177

Reputation: 5 645