Jeegar Patel Jeegar Patel - 5 months ago 18
Linux Question

readlink command misbehave after issueing pushd command in bash scripts

I came across one complex problem I tried to explain it with simple example as below

In my system I have

ubuntu@ubuntu:~/temp$ pwd
/home/ubuntu/temp
ubuntu@ubuntu:~/temp$ ls
temp1 test.sh
ubuntu@ubuntu:~/temp$


In temp.sh I have

#!/bin/bash

echo "Arg 0 = $0"
echo "Arg 1 = $1"
echo "Arg 0 Full Path $(readlink -f $0)"
echo "Arg 1 Full Path $(readlink -f $1)"
pushd /var/log
echo "Arg 0 = $0"
echo "Arg 1 = $1"
echo "Arg 0 Full Path $(readlink -f $0)"
echo "Arg 1 Full Path $(readlink -f $1)"


now I run at below way

ubuntu@ubuntu:~/temp$ ./test.sh temp1
Arg 0 = ./test.sh
Arg 1 = temp1
Arg 0 Full Path /home/ubuntu/temp/test.sh
Arg 1 Full Path /home/ubuntu/temp/temp1
/var/log ~/temp
Arg 0 = ./test.sh
Arg 1 = temp1
Arg 0 Full Path /var/log/test.sh
Arg 1 Full Path /var/log/temp1


Here you can see
readlink
shows wrong path of the Arg0 and Arg1 files after issuing
pushd
command.

If I remove popd command then it prints fine.

So why here
readlink
misbehave?

Answer

Given relative paths, readlink will interpret them relative to process working directory, and output absolute paths (resolving symbolic links inbetween).

The key point here is the process working directory (aka current directory).

So readlink ./path/to/file will output /tmp/path/to/file if /tmp is the current directory (supposing no symbolic links).

The other command you're using, pushd will change the process working directory.

So in the sequence

readlink ./path/to/file
pushd /some/other/place
readlink ./path/to/file

both readlink will likely resolve to two different absolute paths.

No misbehavior here. All by design.