Por que aspas são necessárias para o argumento files ao chamar este script Bash?

13

Sou bastante novo no script Bash. Eu tenho um "script de testes", que usei como base para um script mais avançado / útil:

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

Quando eu ligo sem as aspas, apenas pega um arquivo em um diretório:

testscript *.txt

Mas quando eu o chamo com aspas, ele funciona corretamente e seleciona todos os arquivos de texto:

testscript '*.txt'

O que está acontecendo aqui?

    
por tyebillion 26.08.2016 / 16:06

2 respostas

29

Quando você chama um programa

testscript *.txt

então o seu shell faz a expansão e trabalha todos os valores. Assim, pode efetivamente chamar seu programa como

testscript file1.txt file2.txt file3.txt file4.txt

Agora, o seu programa examina apenas $1 e, portanto, só funciona em file1.txt .

Ao citar na linha de comando, você está passando a string literal *.txt para o script, e é isso que está armazenado em $1 . Seu for loop expande-o.

Normalmente você usaria "$@" e não $1 em scripts como este.

Esta é uma "pegadinha" para pessoas que vêm do script CMD, onde o shell de comando não faz globbing (como é conhecido) e sempre passa a string literal.

    
por 26.08.2016 / 16:10
7

Sem aspas, o shell expande *.txt antes de invocar o script, portanto, $1 é apenas o primeiro arquivo a ser expandido. Todos os arquivos txt são argumentos para seu script nesse ponto (supondo que não haja muitos).

Com aspas essa string é passada sem ser expandida no script, o que permite que o for faça a expansão, como você espera.

    
por 26.08.2016 / 16:09