Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

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.

!basename /scripts/sys/etc.sh
etc.sh

Get File Name and Extensions

%%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.

# 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.

!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.

%%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.

# 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'
!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
%%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

# 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]}
!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
%%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