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.