Search code examples
linuxbashsh

why bash script runs without .sh?


I have a bash script which by mistake has been named with .py (e.g. test.py) This script runs without any problem. (./test.py) In case it might be useful, here is the information from ls -l command: -rwxr-xr-x.

My question is why the script (test.py) executes with out being named correctly as (test.sh) Might it cause a problem?

The script content looks like this:

#!/bin/bash


export SINGULARITYENV_LC_ALL=C.UTF-8
export SINGULARITYENV_LANG=C.UTF-8

CONTAINER=/mnt/pynet-pytorch-181.sif

# Pretrain
DATA=/mnt/Dataset/
EXPERIMENT_NAME=./2022_12_16/


srun -c 4 --gres=gpu:a6000:1 --mem=32G singularity exec -B /mnt:/mnt/ \
--nv $CONTAINER \
python train.py --dataroot $DATA \
               --device "cuda" \
               --pre_denoising False \
               --experiment_name $EXPERIMENT_NAME \
               --epochs 200

I tried running another bash script with the same naming problem *.py again it executes without a problem. I don't understand why it works though.


Solution

  • Unixes don't care about extensions. If the file is executable + readable (for binaries, it doesn't even need to be readable) and starts with #!, the executable that follows it is invoked with the name of the script as its argument.

    In your case, the OS will execute /bin/bash path_to_your_script YourArguments.... And bash doesn't care about extensions either.

    Note: for better portability, you might want to do #!/urs/bin/env bash instead of #!/bin/bash as not all systems have bash at /bin/bash (env will look up the actual path using the $PATH environment variable). Or just use the POSIX shell at /bin/sh. As Elliott Frisch suggests, you might also want to read https://en.wikipedia.org/wiki/Shebang_(Unix) especially if you want mess with custom shebang lines because shebang lines are not scripts themselves and are limited in length (like 128 or 256 bytes) and argument passing: namely they only support argument.