<div dir="ltr"><div><br></div><div>the default erl is a shell script, like this:</div><div><br></div>#!/bin/sh<div>[...]<br><div><div># %CopyrightEnd%</div><div>#</div><div>ROOTDIR="/usr/lib/erlang"</div><div>...</div></div></div><div><br></div><div><br></div><div>Where the ROOTDIR is set to a hard code string at installation time, and it makes the erl script not relocatable,</div><div><br></div><div>sometimes we want to install multiple erlang versions for testing features, like this following is my way to test install esl packaged erlang-20.0-rc2, all just extract "install" to my $HOME/opt/... without sysadmin permission:</div><div><br></div><div># download the deb or rpm package</div><div>$ wget -P ./Downloads -m <a href="https://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb">https://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb</a><br></div><div><br></div><div># the deb is an ar format, you can use standard ar/tar tools to extract to local ./usr/lib/erlang/</div><div>$ ar p ./Downloads/<a href="http://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb">packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb</a> data.tar.xz | tar --xz -xvv ./usr/lib/erlang/</div><div><br></div><div># or to extract the rpm, it is cpio format:</div><div># rpm2cpio ./Downloads/<a href="http://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~centos~6_amd64.rpm">packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~centos~6_amd64.rpm</a> | cpio -vid './usr/lib/erlang/*'<br></div><div><br></div><div>Once I get ./usr/lib/erlang/ I usually renamed to ./opt/ ...</div><div><br></div><div>$ mv -v ./usr/lib/erlang/ ./opt/esl-erlang_20.0-rc2-1~debian~jessie<br></div><div><br></div><div>Then a problem is this erl doesn't run, because it tries to access the hard coded ROOTDIR from /usr/lib/erlang (does not exist)</div><div><br></div><div>(the "bash -xe" is only to show how does the shell script run, but not necessary)</div><div><br></div><div><div>$ bash -xe ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl</div><div>+ ROOTDIR=/usr/lib/erlang</div><div>+ BINDIR=/usr/lib/erlang/erts-9.0/bin</div><div>+ EMU=beam</div><div>++ echo ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl</div><div>++ sed 's/.*\///'</div><div>+ PROGNAME=erl</div><div>+ export EMU</div><div>+ export ROOTDIR</div><div>+ export BINDIR</div><div>+ export PROGNAME</div><div>+ exec /usr/lib/erlang/erts-9.0/bin/erlexec</div><div>./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl: line 29: /usr/lib/erlang/erts-9.0/bin/erlexec: No such file or directory</div></div><div><br></div><div>So I back it up and make little changes to make it read path from where it's installed:</div><div><br></div><div><div>$ \cp -va ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl{,.orig}</div><div>`./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl' -> `./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl.orig'</div></div><div><br></div><div>$ vim ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl<br></div><div><br></div><div>Diff is here:</div><div><br></div><div><div>$ diff -u ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl{.orig,}</div><div>--- ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl.orig<span style="white-space:pre">       </span>2017-06-06 01:57:50.796140791 +0000</div><div>+++ ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl<span style="white-space:pre">      </span>2017-06-06 01:59:15.713988348 +0000</div><div>@@ -18,10 +18,12 @@</div><div> # </div><div> # %CopyrightEnd%</div><div> #</div><div>-ROOTDIR="/usr/lib/erlang"</div><div>+# ROOTDIR="/usr/lib/erlang"</div><div>+ROOTDIR="$(readlink -f ${0%/*}/..)"</div><div> BINDIR=$ROOTDIR/erts-9.0/bin</div><div> EMU=beam</div><div>-PROGNAME=`echo $0 | sed 's/.*\///'`</div><div>+# PROGNAME=`echo $0 | sed 's/.*\///'`</div><div>+PROGNAME="${0##*/}"</div><div> export EMU</div><div> export ROOTDIR</div><div> export BINDIR</div></div><div><br></div><div>Then it runs:</div><div><br></div><div>$ bash -xe ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl<br></div><div><div>++ readlink -f ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/..</div><div>+ ROOTDIR=/home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie</div><div>+ BINDIR=/home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin</div><div>+ EMU=beam</div><div>+ PROGNAME=erl</div><div>+ export EMU</div><div>+ export ROOTDIR</div><div>+ export BINDIR</div><div>+ export PROGNAME</div><div>+ exec /home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin/erlexec</div><div>Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]</div><div><br></div><div>Eshell V9.0  (abort with ^G)</div><div>1> </div></div><div><br></div><div>I am aware of there is a "Install" script can be used to install itself to another location, but the problem remains: it's still hard coded of new install path:</div><div>./opt/esl-erlang_20.0-rc2-1~debian~jessie/Install<br></div><div><br></div><div><br></div><div>The problem need to be solved, especially when used with docker's bind mount feature, it can be mounted to a complete different path, I hope the erl can still run without any change:</div><div><br></div><div>Here it shows my changed erl escript can still run when bind mounted to the container's "/opt/esl-erlang_20.0-rc2-1~debian~jessie"</div><div><br></div><div><div>$ docker run -it --rm -v $PWD/opt:/opt:ro ubuntu bash -xe /opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl</div><div>++ readlink -f /opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/..</div><div>+ ROOTDIR=/opt/esl-erlang_20.0-rc2-1~debian~jessie</div><div>+ BINDIR=/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin</div><div>+ EMU=beam</div><div>+ PROGNAME=erl</div><div>+ export EMU</div><div>+ export ROOTDIR</div><div>+ export BINDIR</div><div>+ export PROGNAME</div><div>+ exec /opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin/erlexec</div><div>Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]</div><div><br></div><div>Eshell V9.0  (abort with ^G)</div><div>1> </div><div>User switch command</div><div> --> q</div></div><div><br></div><div>Or add to PATH:</div><div><br></div><div><div>$ docker run -it --rm -v $PWD/opt:/opt:ro -e PATH=/opt/esl-erlang_20.0-rc2-1~debian~jessie/bin:$PATH -e LANG=C.UTF-8 ubuntu erl +pc unicode</div><div>Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]</div><div><br></div><div>Eshell V9.0  (abort with ^G)</div><div>1> io:format("~tp~n", [{'hello_юникод_世界', <<"Hello, 世界; юникод"/utf8>>, "Hello, 世界; юникод"}]).</div><div>{'hello_юникод_世界',<<"Hello, 世界; юникод"/utf8>>,"Hello, 世界; юникод"}</div><div>ok</div><div>2> </div><div>User switch command</div><div> --> q</div></div><div><br></div><div><br></div><div>Hopefully this entertains; I can make a PR to  <a href="https://github.com/erlang/otp">https://github.com/erlang/otp</a> if somebody like.</div><div><br></div><div><br></div></div>