File Name of Bash Script

Posted on Dec 03, 2019 in Computer Science

Things under legendu.net/outdated are outdated technologies that the author does not plan to update any more. Please look for better alternatives.

Fish Shell is preferred to Bash/Zsh. The following content is for Bash/Zsh only.

  1. Do NOT get into this messy shit if you can avoid it! Use Python script instead if you can.

  2. If you want to reliably get the name of a Bash script, it is recommended that you run the Bash script as an executable script instead of source it in.

  3. There are 2 ways ($0 and ${BASH_SOURCE[0]}) to get the file name of a Bash script. ${BASH_SOURCE[0]} is a more robust way and is preferred.

In [1]:
!basename /scripts/sys/etc.sh
etc.sh

Get File Name and Extensions

In [3]:
%%bash

FILE="example.tar.gz"
echo "${FILE%%.*}"

echo "${FILE%.*}"

echo "${FILE#*.}"

echo "${FILE##*.}"
example
example.tar
tar.gz
gz

$0 vs ${BASH_SOURCE[0]}

The example below shows that ${BASH_SOURCE[0]} is more robust than $0 and is preferred.

In [22]:
# print the content of a Bash script a.sh
!cat bash-file-name/a.sh | highlight -O ansi
#!/bin/bash

echo '$0: '$0
echo '$(readlink -f $0): '$(readlink -f $0)
echo '${BASH_SOURCE[0]}: '${BASH_SOURCE[0]}
echo ' $(readlink -f ${BASH_SOURCE[0]}): '$(readlink -f ${BASH_SOURCE[0]})

Running the Bash script as an executable script.

In [20]:
!bash-file-name/a.sh
$0: bash-file-name/a.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/a.sh
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh

Source in the Bash script.

In [21]:
%%bash

source bash-file-name/a.sh
$0: bash
$(readlink -f $0): /workspace/blog/misc/content/bash
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh

Both $0 and ${BASH_SOURCE[0]} work on symbolic links. You can use readlink to get the raw path of the file.

In [27]:
# create a symbolic link to a.sh as b.sh
!ln -svf $(realpath bash-file-name/a.sh) bash-file-name/b.sh
'bash-file-name/b.sh' -> '/workspace/blog/misc/content/bash-file-name/a.sh'
In [28]:
!bash-file-name/b.sh
$0: bash-file-name/b.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/a.sh
${BASH_SOURCE[0]}: bash-file-name/b.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh
In [29]:
%%bash

source bash-file-name/b.sh
$0: bash
$(readlink -f $0): /workspace/blog/misc/content/bash
${BASH_SOURCE[0]}: bash-file-name/b.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh

Running from Another Script

In [36]:
# c.sh runs a.sh
!cat bash-file-name/c.sh | highlight -O ansi
#!/bin/bash

source bash-file-name/a.sh
bash-file-name/a.sh
echo ${BASH_SOURCE[0]}
In [32]:
!bash-file-name/c.sh
$0: bash-file-name/c.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/c.sh
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh
$0: bash-file-name/a.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/a.sh
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh
bash-file-name/c.sh
In [34]:
%%bash

bash-file-name/c.sh
$0: bash-file-name/c.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/c.sh
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh
$0: bash-file-name/a.sh
$(readlink -f $0): /workspace/blog/misc/content/bash-file-name/a.sh
${BASH_SOURCE[0]}: bash-file-name/a.sh
 $(readlink -f ${BASH_SOURCE[0]}): /workspace/blog/misc/content/bash-file-name/a.sh
bash-file-name/c.sh