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.