Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Why You Lose OLDPWD in Erlang on MacOSX

View 0_Introduction.md

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
/Users/mirell/src/ubuntu/bash
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").
false
2> 

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:

#!/bin/sh
ROOTDIR=/usr/local/Cellar/erlang/R15B01/lib/erlang
BINDIR=$ROOTDIR/erts-5.9.1/bin
EMU=beam
PROGNAME=`echo $0 | sed 's/.*\///'`
export EMU
export ROOTDIR
export BINDIR
export PROGNAME
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.

Sigh.

View 0_Introduction.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Using /bin/sh
mac:~echo $OLDPWD
/Users/mirell/src/bitbucket
mac:~ ∴ sh
sh-3.2$ echo $OLDPWD
 
sh-3.2$
 
# Using /bin/bash
mac:~echo $OLDPWD
/Users/mirell/src/ubuntu/bash
mac:~ ∴ bash
mac:~echo $OLDPWD
 
mac:~
 
# /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.
View 0_Introduction.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# Using /bin/sh
mirell@linux:~$ echo $OLDPWD
/home/mirell/src/kerl
mirell@linux:~$ sh
$ echo $OLDPWD
/home/mirell/src/kerl
$
 
# Using /bin/bash
mirell@linux:~$ echo $OLDPWD
/home/mirell/src/kerl
mirell@linux:~$ bash
mirell@linux:~$ echo $OLDPWD
 
mirell@linux:~$
 
# /bin/sh symlink:
mirell@linux:~$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2011-09-24 13:37 /bin/sh -> dash
mirell@linux:~$
View 0_Introduction.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Using /bin/sh
[root@smartos ~]# echo $OLDPWD
/home/jill
[root@smartos ~]# sh
# echo $OLDPWD
/home/jill
 
# Using /bin/bash
[root@smartos ~]# echo $OLDPWD
/home/jill
[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 ~]#
View 0_Introduction.md
1 2 3 4 5 6
/* 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.