O que $ {0% / *} nos scripts shell faz?


17

Desculpe se esta é uma pergunta estúpida, mas eu pesquisei sem sucesso.

O que exatamente a segunda linha faz?

#!/bin/sh
cd ${0%/*} || exit 1

Eu sei que o primeiro é o shebang, o segundo tenta mudar de diretório, mas a parte confusa é ${0%/*}.

Você pode me explicar essa segunda linha?


2
Conforme explicado por Andrea em uma resposta, $ {0% / *} se traduz no caminho do diretório prefixado para o nome do script enquanto o invoca. Uma alternativa é usar o dirnamecomando $(dirname $0)
interno

@alwayslearning: Qual versão do shell e do shell você está usando dirnamee incorporada? Certamente não está no Bash v4.3.11, que é o shell padrão no Ubuntu Trusty.
precisa saber é o seguinte

Minhas desculpas pela confusão, acabei de verificar que dirnamenão é um shell embutido.
alwayslearning

Respostas:


27

${0}é o primeiro argumento do script, ou seja, o nome ou caminho do script. Se você lançar o seu script como path/to/script.sh, em seguida, ${0}será exatamente essa seqüência: path/to/script.sh.

A %/*parte modifica o valor de ${0}. Significa: use todos os caracteres até ser /seguido por um nome de arquivo. No exemplo acima, ${0%/*}será path/to.

Você pode vê-lo em ação no seu shell:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh suporta muitos outros tipos de "substituição de parâmetro". Aqui está, por exemplo, como usar o nome do arquivo em vez do caminho:

$ echo "${x##*/}"
script.sh

Em geral, %e %%sufixos de tira, enquanto #e ##prefixos de tira. Você pode ler mais sobre a substituição de parâmetros .


2
Essa "|| saída 1" parece ser desnecessária: se será agora mudar de dir $? é igual a 1.
Josef Klimuk

2
Seria bom mencionar que a construção está documentada como "Remover padrão de prefixo / sufixo correspondente" no manual. Também é uma boa maneira de lembrar qual é o número # no turno 3 ( esquerda de $),% no turno 5 ( direita de $), pelo menos no teclado dos EUA.
Chexum

1
@ JosefKlimuk: || exit 1 pode ser necessário porque cdpode sair com o status 2, não 1, por erro. No entanto, concordo que não é muito útil (geralmente os programas não se preocupam com status de saída específicos). Provavelmente isso faz parte de um script maior?
Andrea Corbellini

1
@AndreaCorbellini Certamente certo. Praticamente, a única maneira de usar alguma utilidade é como parte de um script maior. Um script que apenas altera o diretório atual não tem efeito, porque afeta apenas o shell executando esse script. O processo pai nunca o vê.
hvd
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.