home/*
e *
são shell globs, eles são expandidos primeiro pelo shell (portanto, aqui executando como você mesmo, não com privilégios de superusuário), e as palavras resultantes são então passadas como argumento para o comando.
Então, se home
contiver .
, ..
, .hidden
. u1
, u2
e o diretório atual contém .
, ..
, .hidden
, -i
, x
, y
, os argumentos que mv
receberão são mv
, home/u1
, home/u2
, -i
, x
, y
.
Algumas implementações de mv
como o GNU mv
têm uma má característica de que os argumentos que começam com -
ainda são reconhecidos como opções, mesmo se ocorrerem após argumentos não opcionais, portanto acima de -i
seria considerado como A opção -i
para mv
( sudo
não tem essa má função por razões óbvias).
y
seria tomado por mv
como o diretório de destino, e é aí que os arquivos desapareceriam se y
fosse do tipo diretório (ou link simbólico para o diretório).
mv
não verá um argumento *
ou home/*
(a menos que existam arquivos com nomes assim, é claro). No entanto, note que alguns shells como a maioria dos Bourne-like têm essa má característica de que se o glob não corresponder a nenhum arquivo, ele é passado como está (unexpanded) para o comando.
Portanto, com esses, se o diretório atual contiver apenas arquivos ocultos, mv
receberia *
como o último argumento. mv
não trata *
especialmente (é o papel do shell para entender globs), então ele tratará como o nome literal do diretório de destino. Agora, se não houver nenhum arquivo não oculto, esse diretório *
também não existirá, então mv home/u1 home/u2 *
apenas relataria um erro sobre o diretório de destino não existente. Se houvesse apenas u1
em home
, mv home/u1 *
tornaria mv
renomear home/u1
para *
no diretório atual.
Esse erro foi introduzido pelo shell Bourne em 1979. Nas versões anteriores do Unix (e no csh que não o alterou), o comando é cancelado se nenhum dos globs corresponder. Os globs foram então expandidos por um /etc/glob
helper (que deu seu nome a globs). Se pelo menos um glob correspondesse a qualquer arquivo, os globs não correspondentes seriam removidos. Portanto, em csh / tcsh (ou zsh -o cshnullglob
) um mv home/* *
em que o diretório atual não tem nenhum arquivo não oculto se tornaria mv home/u1 home/u2
, o que moveria u1
para u2
.
Os shells modernos, como zsh
ou fish
(ou bash -o failglob
), o corrigiram cancelando o comando se algum dos globs não corresponder.