Por que há um sinal de menos em "$ 0" no Mac?

5

Sou usuário do GNU / Linux há anos, mas não consigo descobrir como obter informações úteis sobre o processo no Mac.

Percebi que $0 resolve para -bash no meu shell de login no Mac OS (Snow Leopard). Isso pode quebrar certos scripts de shell que funcionam bem em um ambiente Linux *.

Infelizmente, a manpage não menciona esse fato

If bash is invoked with a file of commands, $0 is set to the name of that file. If bash is started with the -c option, then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the file name used to invoke bash, as given by argument zero.

O sinal de menos tem um significado especial?  Existe algo como /proc ou uma ferramenta de linha de comando que poderia me ajudar a encontrar o executável associado?

* Bobo eu. Naturalmente, $ 0 irá avaliar o nome do script, conforme indicado no manual

    
por user123444555621 12.09.2010 / 10:37

3 respostas

6

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:

  1. um nome de arquivo, que deve designar um arquivo executável existente. O kernel carrega este arquivo e transfere a execução para ele.

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

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

    
por 12.09.2010 / 13:13
1

De man bash :

exec [-cl] [-a name] [command [arguments]]
If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. ...

    
por 12.09.2010 / 16:01
0

Eu não tenho certeza do que está acontecendo com o -bash, mas se você executar o bash novamente no shell, o valor de $ 0 parece estar bem.

Parece ser algo especial que o os x está fazendo, porque se você executar / usr / bin / login, que é o script padrão usado pelo programa terminal, o mesmo problema com $ 0 aparecerá.

    
por 12.09.2010 / 11:09