$0 does not mean "path to my program". That's what it traditionally is, and it's what you get whenever a shell runs a program, but when something that's not a shell runs your program, that's not guaranteed by any means. cron will give weird values for $0. CGI gives weird values for $0. And so forth.
So yes... It does when you run it, from a terminal, giving it an absolute path. When things other than you run it, from non-terminals, in ways and from places you never did, you might get something else.
These two C programs show how it works:
$ cat printzero.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("$0 is %s\n", argv[0]);
}
$ cat zero.c
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc < 2)
{
fprintf(stderr, "usage: ./zero program zeroth-argument\n");
return(1);
}
// First argument is the program name and path. Second is $0.
// Note that NOTHING forces them to be the same.
execl(argv[1], argv[2], NULL);
return(1);
}
$ gcc zero.c -o zero
$ gcc printzero.c -o printzero
$ ./printzero
$0 is ./printzero
$ ./zero ./printzero slartibartfast
$0 is slartibartfast
$
So, when you run ./printzero by itself, the shell runs it, and $0 is what you expect.
When the zero program runs printzero, it can give whatever weird and wild value it wants to $0, and does.
Some shells will make a halfhearted attempt to correct the value of $0 into something 'useful', but they're not psychic. They can't recover paths they were never given in the first place.
So $0 is only what the program calling it says it is. It's not necessarily the information you want. Do not depend on it if you want your scripts to be run by cron and the like.