Eu sou bastante novo no script Bash. Eu tenho um "testingcript", 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 chamo isso sem 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?
bash
shell-script
gornvix
fonte
fonte
for a in "$@"; do
(oufor a; do
) em seu script, deixando o globbing para o shell externo, para não deixar de fora as aspas.Respostas:
Quando você chama um programa
então seu shell faz a expansão e calcula todos os valores. Portanto, pode chamar efetivamente seu programa como
Agora seu programa apenas analisa
$1
e, portanto, apenas funcionafile1.txt
.Ao citar na linha de comando, você está passando a string literal
*.txt
para o script, e é isso que está armazenado$1
. Seufor
loop então o expande.Normalmente você usaria
"$@"
e não$1
em scripts como este.Essa é uma "pegadinha" para pessoas provenientes de scripts CMD, em que o shell de comando não faz globbing (como é conhecido) e sempre passa a string literal.
fonte
"$@"
(ao contrário$@
ou$1
$2
$3
) fará com que cada nome de arquivo para ser citado"file1.txt"
"file2.txt"
etc. Porfile1.txt
isso não tem sentido, mas se você tivermy file.txt
, a citação é fundamental para evitar que o shell análise para transformá-lo em dois nomes de arquivos, um nomeadomy
e outro nomeadofile.txt
. Sempre cite a entrada do usuário e a expansão global para que você não fique muito satisfeito algum dia.Sem aspas, o shell se expande
*.txt
antes de invocar o script, assim$1
como apenas o primeiro arquivo que é expandido. Todos ostxt
arquivos são argumentos para o seu script nesse ponto (supondo que não haja muitos).Com aspas, essa string é passada sem ser expandida para o script, que permite
for
a expansão, como você espera.fonte