Skip to main content
added 53 characters in body
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46

Bash comes with a realpath loadable extension. Since bash-4.4 this should be installed by default¹, so you should be able to do:

BASH_LOADABLES_PATH=${BASH_LOADABLES_PATH:-/usr/local/lib/bash:/usr/lib/bash}
enable -f realpath realpath
realpath ..
help realpath

Once enabled, each loadable command becomes a "real" builtin with no additional fork/exec overhead, and with the ability to manipulate the bash environment (where offered, e.g. the mypid loadable)..

The -f option specifies the path to the loadable extension binary, if it's not in the expected place or your distro didn't set it correctly, you will need to set the variable BASH_LOADABLES_PATH to the directory containing extensions (or, use -f with the full path to the loadable). If it's set correctly, you won't need the first line above.

When writing portable scripts that prefer, but do not require such extensions, I will use a wrapper function anyway — along the lines of @Kusalananda's — so that it can fall back to an external (such as readlink or realpath from coreutils).


  1. This extension is available since bash-2.05, but prior to bash-4.4 extensions were not compiled and installed by default, though it is straightforward to do so if you have a working build environment (C compiler etc.). Distributions may or may not include the extensions, sadly RHEL 8 (and hence CentOS 8) build bash-4.4 with the loadable extensions deliberately removed.

Bash comes with a realpath loadable extension. Since bash-4.4 this should be installed by default¹, so you should be able to do:

BASH_LOADABLES_PATH=${BASH_LOADABLES_PATH:-/usr/local/lib/bash:/usr/lib/bash}
enable -f realpath realpath
realpath ..
help realpath

Once enabled, each command becomes a "real" builtin with no additional fork/exec overhead, and with the ability to manipulate the bash environment.

The -f option specifies the path to the loadable extension binary, if it's not in the expected place or your distro didn't set it correctly, you will need to set the variable BASH_LOADABLES_PATH to the directory containing extensions (or, use -f with the full path to the loadable). If it's set correctly, you won't need the first line above.

When writing portable scripts that prefer, but do not require such extensions, I will use a wrapper function anyway — along the lines of @Kusalananda's — so that it can fall back to an external (such as readlink or realpath from coreutils).


  1. This extension is available since bash-2.05, but prior to bash-4.4 extensions were not compiled and installed by default, though it is straightforward to do so if you have a working build environment (C compiler etc.). Distributions may or may not include the extensions, sadly RHEL 8 (and hence CentOS 8) build bash-4.4 with the loadable extensions deliberately removed.

Bash comes with a realpath loadable extension. Since bash-4.4 this should be installed by default¹, so you should be able to do:

BASH_LOADABLES_PATH=${BASH_LOADABLES_PATH:-/usr/local/lib/bash:/usr/lib/bash}
enable -f realpath realpath
realpath ..
help realpath

Once enabled, each loadable command becomes a "real" builtin with no additional fork/exec overhead, and with the ability to manipulate the bash environment (where offered, e.g. the mypid loadable)..

The -f option specifies the path to the loadable extension binary, if it's not in the expected place or your distro didn't set it correctly, you will need to set the variable BASH_LOADABLES_PATH to the directory containing extensions (or, use -f with the full path to the loadable). If it's set correctly, you won't need the first line above.

When writing portable scripts that prefer, but do not require such extensions, I will use a wrapper function anyway — along the lines of @Kusalananda's — so that it can fall back to an external (such as readlink or realpath from coreutils).


  1. This extension is available since bash-2.05, but prior to bash-4.4 extensions were not compiled and installed by default, though it is straightforward to do so if you have a working build environment (C compiler etc.). Distributions may or may not include the extensions, sadly RHEL 8 (and hence CentOS 8) build bash-4.4 with the loadable extensions deliberately removed.
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46

Bash comes with a realpath loadable extension. Since bash-4.4 this should be installed by default¹, so you should be able to do:

BASH_LOADABLES_PATH=${BASH_LOADABLES_PATH:-/usr/local/lib/bash:/usr/lib/bash}
enable -f realpath realpath
realpath ..
help realpath

Once enabled, each command becomes a "real" builtin with no additional fork/exec overhead, and with the ability to manipulate the bash environment.

The -f option specifies the path to the loadable extension binary, if it's not in the expected place or your distro didn't set it correctly, you will need to set the variable BASH_LOADABLES_PATH to the directory containing extensions (or, use -f with the full path to the loadable). If it's set correctly, you won't need the first line above.

When writing portable scripts that prefer, but do not require such extensions, I will use a wrapper function anyway — along the lines of @Kusalananda's — so that it can fall back to an external (such as readlink or realpath from coreutils).


  1. This extension is available since bash-2.05, but prior to bash-4.4 extensions were not compiled and installed by default, though it is straightforward to do so if you have a working build environment (C compiler etc.). Distributions may or may not include the extensions, sadly RHEL 8 (and hence CentOS 8) build bash-4.4 with the loadable extensions deliberately removed.