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

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

Sou usuário GNU/Linux há anos, mas não consigo descobrir como obter informações de processo utilizáveis ​​no Mac.

Percebi que isso $0resolve -bashno 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 página de manual não menciona esse fato

Se o bash for invocado com um arquivo de comandos, $0 será definido como o nome desse arquivo. Se o bash for iniciado com a opção -c, então $0 será definido como o primeiro argumento após a string a ser executada, se houver alguma presente. Caso contrário, é definido como o nome do arquivo usado para invocar o bash, conforme fornecido pelo argumento zero.

O sinal de menos tem um significado especial? Existe algo parecido /procou uma ferramenta de linha de comando que possa me ajudar a encontrar o executável associado?

* Bobo eu. Claro, $0 será avaliado como o nome do script, conforme indicado no manual

Responder1

O sinal de menos é a maneira como o sistema informa ao shell que ele é invocado como um shell de login e deve ser fonte ~/.profile(para shells compatíveis com Bourne). Isso é verdade no Linux, OSX e em 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 de manual explica (quase todos) os diferentes casos:

  • “Se o bash for invocado com um arquivo de comandos, $0 será definido como o nome desse arquivo.” Isso abrange 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 for iniciado com a opção -c, então $0 será definido como o primeiro argumento após a string a ser executada, se houver alguma.” Com -c, $0é definido como o que o chamador indica explicitamente.

  • “Caso contrário, é definido como 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 nenhum argumento além do argumento zero, portanto $0é definido como argumento zero. É login, su, ou qualquer outro programa que tenha manipulado o login que escolhe os argumentos que ele passou para o shell e acrescenta um -ao argumento zero para informar ao shell que é um shell de login.

Talvez alguma explicação do argumento zero seja necessária. Quando um programa é executado, em última análise, execveocorre uma chamada de sistema. 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 nesta matriz épor convençãoo mesmo nome de arquivo acima ou apenas o nome do arquivo sem o caminho completo se a localização do executável foi determinada pela pesquisa na $PATHvariável de ambiente. Existem exceções a esta 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 execvesão:
    1. /usr/bin/myprogram(assumindo que foi aqui que o shell foi encontrado myprogram)
    2. myprogram, foo, bar
    3. para cada variável do shell exportada, o nome da variável seguido por um sinal de igual e o valor .

Não existe uma maneira geral de encontrar o nome do arquivo executável que foi passado execvedo programa em execução. No Linux, geralmente está disponível /proc/$$/exeonde $$está o ID do processo. Todo unix o disponibiliza, psmas o funcionamento interno psdifere amplamente. O executável pode ser excluído ou renomeado enquanto o programa está em execução; neste caso, pspode reportar informações obsoletas ou nenhuma informação.

Responder2

De man bash:

exec [-cl] [-a nome] [comando [argumentos]]
Se o comando for especificado, ele substituirá o shell. Nenhum novo processo é criado. Os argumentos tornam-se os argumentos para comandar. Se a opção -l for fornecida, o shell colocará um travessão no início do argumento zero passado ao comando. Isso é o que login(1) faz. ...

Responder3

Não tenho certeza do que está acontecendo com -bash , mas se você executar o bash novamente no shell, o valor $0 parecerá adequado.

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 de terminal, o mesmo problema com $0 aparece.

informação relacionada