Como armazenar um caminho construído com curingas e contendo espaços em uma variável

5

Aqui está a situação (estou em um Mac, OS X El Capitan):

# This works:

$ cd /Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates/;

# These do not work:

$ INSTALL_DIR=/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates;
$ cd $INSTALL_DIR
# Moves me here: /Applications/Adobe

$ cd "$INSTALL_DIR"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

$ cd "${INSTALL_DIR}"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

Meu objetivo é usar $INSTALL_DIR em tar da seguinte forma:

$ tar -xz $SOURCE_ZIP --strip-components 1 -C $INSTALL_DIR "*.ait";

Infelizmente, o -C (mudando para o diretório de destino) não gosta dos espaços em $INSTALL_DIR ; se eu usar aspas, não consigo fazer o * funcionar.

Existe uma maneira elegante de lidar com esse cenário?

    
por mhulse 24.01.2016 / 04:54

2 respostas

2

Quando o * não é citado, o shell expande a lista de argumentos antes de executar o comando. Ele passa a lista de argumentos de expansão para o programa.

Quando o * aparece em uma string entre aspas, ele não é expandido pelo shell antes de ser passado para o programa.

Tente expandir o caminho, atribuindo-o a outra variável e, em seguida, citando a segunda variável ao transmiti-la como um argumento.

    
por 24.01.2016 / 05:06
0

O problema não é tar, está no seu código shell. O argumento da opção -C deve ser um caminho, não um padrão de caractere curinga. Observe que você teve exatamente o mesmo problema com o comando cd .

Você armazenou um padrão curinga na variável INSTALL_DIR . Quando você escreve -C $INSTALL_DIR , isso aplica o operador “split + glob”: pegue o valor da variável, divida-o no espaço em branco e interprete cada palavra como um padrão curinga que é então expandido. Aqui, o valor da variável é /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates , que é dividido em três palavras /Applications/Adobe , Illustrator*/Cool , Extras.localized/en_US/Templates ; a palavra do meio contém um caractere curinga ( * ), portanto, ele é interpretado como um padrão curinga, mas como não corresponde a nenhum arquivo, o padrão é deixado como está. Isso torna o argumento da opção -C a string /Applications/Adobe e, em seguida, há mais dois argumentos para o comando tar : Illustrator*/Cool e Extras.localized/en_US/Templates .

Se você usa aspas duplas, então "$INSTALL_DIR" é simplesmente o valor da variável INSTALL_DIR . Com o * ainda nele, uma vez que nunca foi expandido em nenhum ponto.

Como regra geral, os curingas são expandidos em contextos nos quais várias palavras são esperadas. Afinal, em geral, os padrões de caracteres curinga correspondem a vários arquivos. O lado direito de uma atribuição suprime a expansão de curingas, pois espera-se que o resultado seja uma única sequência. Para obter uma lista, atribua a uma variável de array em vez de uma variável de string:

INSTALL_DIRS=(/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates)

Pode haver vários elementos de matriz, se você tiver várias versões do Illustrator instaladas. Vamos pegar o último elemento.

INSTALL_DIR=${INSTALL_DIRS[$((${#INSTALL_DIRS}-1))]}

Agora, INSTALL_DIR é um caminho para um arquivo existente (supondo que o curinga tenha correspondido). Você pode usá-lo normalmente (ou seja, você pode expandi-lo entre aspas duplas).

tar -xz "$SOURCE_ZIP" --strip-components 1 -C "$INSTALL_DIR" "*.ait"
    
por 24.01.2016 / 23:48