Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
Why You Lose OLDPWD in Erlang on MacOSX

Loss of OLDPWD in Erlang on MacOSX

I was wanting to use OLDPWD in Erlang, since the script that initially calls the application changes directories. However, I noticed it wasn't there:

mac:~echo $OLDPWD
mac:~ ∴ erl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1> os:getenv("OLDPWD").

It worked on Linux (Ubuntu) and SmartOS though. This was incredibly puzzling.

After digging through the source code of Erlang for hours, trying to see if it was somehow discarding certain environment variables, I finally stumbled upon the fact that erl is a shell script:

PROGNAME=`echo $0 | sed 's/.*\///'`
export EMU
export ROOTDIR
export BINDIR
exec $BINDIR/erlexec ${1+"$@"}

The fact it was using /bin/sh made me wonder about POSIX compatability, or something of that nature. It eventually turned out that it's entirely due to the fact that MacOSX uses bash for /bin/sh. Ubuntu uses /bin/dash, SmartOS uses /bin/ksh93.

Bash itself resets the OLDPWD environment variable on startup to "save space", not bothering to check if it was already set.


# Using /bin/sh
mac:~echo $OLDPWD
mac:~ ∴ sh
sh-3.2$ echo $OLDPWD
# Using /bin/bash
mac:~echo $OLDPWD
mac:~ ∴ bash
mac:~echo $OLDPWD
# /bin/sh symlink (or lack thereof)
mac:~ ∴ ls -l /bin/sh
-r-xr-xr-x 1 root wheel 1371712 Oct 10 2011 /bin/sh
# /bin/sh version
mac:~ ∴ /bin/sh --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
# Using /bin/sh
mirell@linux:~$ echo $OLDPWD
mirell@linux:~$ sh
$ echo $OLDPWD
# Using /bin/bash
mirell@linux:~$ echo $OLDPWD
mirell@linux:~$ bash
mirell@linux:~$ echo $OLDPWD
# /bin/sh symlink:
mirell@linux:~$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2011-09-24 13:37 /bin/sh -> dash
# Using /bin/sh
[root@smartos ~]# echo $OLDPWD
[root@smartos ~]# sh
# echo $OLDPWD
# Using /bin/bash
[root@smartos ~]# echo $OLDPWD
[root@smartos ~]# bash
[root@smartos ~]# echo $OLDPWD
[root@smartos ~]#
# /bin/sh symlink
[root@smartos ~]# ls -l /bin/sh
lrwxrwxrwx 1 root root 5 2012-01-26 16:05 /bin/sh -> ksh93
[root@smartos ~]#
/* According to the Single Unix Specification, v2, $OLDPWD is an
`environment variable' and therefore should be auto-exported.
Make a dummy invisible variable for OLDPWD, and mark it as exported. */
temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
VSETATTR (temp_var, (att_exported | att_invisible));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.