O sinal de menos é a maneira como o sistema informa ao shell que é invocado como um shell de login e deve obter ~/.profile (para shells compatíveis com Bourne). Isto é verdade no Linux, OSX e todos os outros unix. Um script não seria executado em um shell de login. Para um script, $0 é o nome do arquivo de script (com ou sem o caminho completo).
ADICIONADO : a página man explica (quase todos) os diferentes casos:
-
"Se bash é chamado com um arquivo de comandos, $ 0 é definido como o nome desse arquivo." Isso abrange os scripts executados com
bash myscript, bem como o caso indireto em que o script é executado diretamente e começa com#!/bin/bash. -
“Se o bash é iniciado com a opção -c, então $ 0 é definido como o primeiro argumento após a sequência a ser executada, se houver uma presente.” Com
-c,$0é definido como qualquer o chamador indica explicitamente. -
“Caso contrário, ele é configurado para o nome do arquivo usado para invocar o bash, conforme fornecido pelo argumento zero.” Um shell de login se enquadra neste caso: o shell é invocado sem argumentos além do argumento zero, portanto
$0é definido como argumento zero. Élogin,su, ou qualquer programa que tenha manipulado o login que escolhe os argumentos que ele passou para o shell, e adiciona um-ao argumento zero para informar ao shell que é um shell de login.
Talvez alguma explicação do argumento zero esteja em ordem. Quando um programa é executado, em última análise, ocorre uma chamada de sistema execve . Essa chamada de sistema leva três argumentos:
-
um nome de arquivo, que deve designar um arquivo executável existente. O kernel carrega este arquivo e transfere a execução para ele.
-
uma matriz de strings, chamada de argumentos. O elemento zero nessa matriz é por convenção o mesmo nome de arquivo acima, ou apenas o nome do arquivo sem o caminho completo, se a localização do executável tiver sido determinada pesquisando a variável de ambiente
$PATH. Há exceções para essa convenção, como shells de login. -
outra matriz de strings, chamada ambiente.
Quando você chama um programa do shell digitando myprogram foo bar , os argumentos para execve são:
1. /usr/bin/myprogram (assumindo que este é o local onde o shell encontrou myprogram )
2. myprogram , foo , bar
3. para cada variável de shell exportada, o nome da variável seguido por um sinal de igual e o valor.
Não há uma maneira geral de encontrar o nome do arquivo executável que foi passado para execve do programa em execução. No Linux, geralmente está disponível como /proc/$$/exe , em que $$ é o ID do processo. Cada unix disponibiliza para ps , mas o funcionamento interno de ps difere amplamente. O executável pode ser excluído ou renomeado enquanto o programa está sendo executado; Nesse caso, ps pode reportar informações obsoletas ou nenhuma informação.