Se o nome já estiver em minúsculas, ele será dado ao comando mv duas vezes, como você viu.
Se o último argumento para mv for um diretório, ele será tratado como o diretório de destino no qual todas as outras entidades nomeadas devem ser movidas.
mv test test
verificará primeiro o último argumento, se existe e, em caso afirmativo, se é um diretório. Nesse caso, o mv verificará se é o mesmo ponto de montagem (se não for, ou seja, o destino é um dispositivo diferente, será necessário copiar o arquivo e, em seguida, remover o original); neste caso, é. Então mv constrói uma seqüência de rename(2)
syscalls, anexando todos os nomes de origem ao diretório especificado como o destino: mv a b c d/
geraria rename("a", "d/a")
, rename("b", "d/b")
e rename("c", "d/c")
- então é claro que mv test test
será tente chamar rename("test", "test/test");
. O que obviamente é um erro, você não pode mover um diretório dentro de si mesmo.
Para consertar seu problema, torne o comando mv condicional ao novo nome sendo diferente e não existente (se você tiver dois arquivos diferentes chamados "Test" e "test", você provavelmente não deseja substituir o segundo sem Perguntando). Sem eu ter testado isso, e digitando-o em um telefone, será algo parecido com isto: new="$(echo "$old" | tr ...)"; [[ $new != $old && ! -e $new ]] && mv "$old" "$new"
(veja as aspas, você não quer espaços em nomes para lhe dar wedgies metafóricos).