livro-shell icon indicating copy to clipboard operation
livro-shell copied to clipboard

O que ${0#-} faz ?

Open niloct opened this issue 4 years ago • 5 comments

https://github.com/aureliojargas/livro-shell/blob/fcc6c06d49d1b466c7a552b920b296e030d02e21/C-funcoeszz/funcoeszz-utf8#L74

Boa noite Aurelio, tudo bem ?

Primeiramente parabéns pelo livro. Estou no apendice das funçõeszz e surgiu uma dúvida, será que vc pode esclarecê-la ?

Não entendi o que ${0#-} faz. Ele procura pelo menor prefixo que contém - no parâmetro 0 (i.e. o arquivo chamado) ?

O primeiro entendi, ele remove o prefixo do início do path do arquivo até a última barra, pelo uso do double dash.

Obrigado.

niloct avatar Apr 01 '21 03:04 niloct

Bom, descobri. Ele remove um hífen do começo do nome do arquivo, se é o primeiro caractere no nome.

Pra q vc precisou fazer isso ?

niloct avatar Apr 01 '21 16:04 niloct

Oi @niloct

Você acertou, a primeira parte é o mesmo que faz o comando basename, removendo todo o path do arquivo e deixando só o último componente:

$ basename /usr/bin/bash
bash
$
$ foo=/usr/bin/bash
$ echo "${foo#*/}"
usr/bin/bash
$ echo "${foo##*/}"
bash
$

Já a segunda parte, do "${0#-}" != "$0", é um teste para "o $0 começa com hífen?".

O jeito de se fazer esse teste, porém, é meio bizarro: remova um possível hífen do início e compare o resultado com o valor original; se houve mudança, foi detectado o hífen no início. Foi feito assim pra ser mais portável e não depender de features mais novas do bash. Outra maneira portável de se fazer o mesmo teste seria echo "$0" | grep '^-'.

De volta à linha original:

[ "${0##*/}" = 'bash' -o "${0#-}" != "$0" ] || ZZPATH="$0" 

A ideia aqui é detectar se o script funcoeszz foi chamado como um executável ou se foi chamado via o comando source. Se foi via executável, podemos garantir que $0 contém o path para o script, por isso setamos $ZZPATH com ele.

Note que é um OU (||), então os dois testes tentam detectar quando não é uma chamada pelo executável. Nesse caso, o bash define $0 como bash ou como alguma string iniciada por hífen. Veja um exemplo:

# teste.sh, arquivo executável com apenas um comando:
echo $0
$ ./teste.sh
./teste.sh
$ source teste.sh 
bash
$

Tou tentando lembrar aqui quando acontece o segundo caso, de iniciar com hífen, mas não lembrei. Também não achei nada buscando no Google. Vou ficar devendo essa :)

aureliojargas avatar May 02 '21 21:05 aureliojargas

Oi Aurélio, beleza ?!

Obrigado pela resposta e detalhes!

Sobre o hífen, acontece só com este caso:

https://askubuntu.com/questions/368509/why-is-0-set-to-bash

Assim, se vc faz $ echo $0, o output é -bash, e me parece que é o único output de $0 que pode começar com -, indicando que o shell atual foi chamado em um login.

Esse link também ajudou: https://unix.stackexchange.com/questions/292588/why-does-bash-c-echo-0-output-bash/

niloct avatar May 02 '21 22:05 niloct

Ah, boa! Muito obrigado pelo seu tempo e por ter procurado essa resposta. ❤️

Se eu tivesse colocado um comentário lá no código das funcoeszz sobre isso... Por sinal, você gostaria de fazer esta contribuição? Será sua terceira no projeto. Fique à vontade para recusar :)

aureliojargas avatar May 13 '21 07:05 aureliojargas

De nada :)

Ponho sim. Vou tentar sintetizar o comentário lá.

niloct avatar May 13 '21 16:05 niloct