O que faz o comando “sudo mv home / * *”? [duplicado]

0
    

Esta pergunta já tem uma resposta aqui:

    

Eu conheço cada parte deste comando.

sudo mv home/* *
  • sudo : super usuário, execute com privilégios de root.
  • mv : mova um arquivo ou diretório.
  • home/* : argumento do comando mv. Indica o conteúdo do diretório inicial. O asterisco * é um curinga que se expande para a lista de arquivos no diretório atual em ordem lexicográfica.

O próximo argumento é a pasta de destino. No entanto, eu especifico um asterisco como diretório de destino, e se eu executar o comando a pasta desaparece completamente. Então, o que o * nesse caso?

    
por JCMiguel 22.05.2018 / 15:37

3 respostas

3

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.

    
por 22.05.2018 / 16:02
1

Tudo depende do que os padrões de globalização expandem.

Ele faz uma das três coisas:

  1. Se o * no final do comando se expandir para uma lista de nomes e o último item dessa lista for o nome de um diretório , o comando moverá tudo que home/* expande para e tudo o que * expande para (mas não esse último nome de diretório) nesse diretório. Os arquivos e diretórios correspondentes a home/* serão encontrados ao lado do diretório home no diretório de destino, se home/* expandir para qualquer coisa e se o diretório de destino ainda não contiver um diretório home .

  2. Se o * no final do comando se expandir para uma lista de nomes e o último item nessa lista for o nome de algo que não é um diretório, o comando produzirá um erro.

  3. Se * não for expandido (porque o diretório atual está vazio), será produzido um erro.

Se usar mv do GNU coreutils e o último * corresponder a um ou vários nomes que iniciam com um traço, isso pode alterar o que o comando faz dependendo de quais opções mv interpretam o nome como.

    
por 22.05.2018 / 16:23
0

Quando eu mesmo fiz isso, acabei criando uma pasta chamada * na minha pasta de destino, e também me livrei dos arquivos de origem dos quais eu estava pegando. Depois de mais alguns testes, o comportamento esperado de ' * não é um diretório' retornado e um novo diretório chamado * não foi criado.

Acredito que isso esteja mais de acordo com a pergunta, pois ele indica que os arquivos dele desapareceram e echo * retorna * .

    
por 22.05.2018 / 16:37