Quem lida com a estrela * em eco *

15

Quem lida (interpreta) o * em

echo *

O eco vê a estrela ou a concha se preocupa com isso e retorna uma lista de nome de arquivo.

A respeito

cp temp temp*
faressoft
fonte
14
Varia. Conchas do Unix ou do Windows?
user1686
conchas @grawity Unix. Desculpe, eu não mencionei isso.
faressoft
Para o Unix, as respostas abaixo estão corretas. (No Windows, isso é feito por programas individuais - embora geralmente automaticamente pela biblioteca de tempo de execução antes de main ().)
user1686

Respostas:

24

bash (ou o que você usar como shell), é a primeira coisa a ler qualquer entrada e começará a interpretar caracteres especiais como ?e *. *é expandido para quaisquer correspondências no CWD , o que significa que o asterisco é substituído pelas referidas correspondências.

Na maioria dos casos, isso é bastante complicado, mas pode levar a alguns casos confusos de tempos em tempos.

Considere o seguinte. Um diretório possui este conteúdo:

  • teste (arquivo regular)
  • test1 (diretório)
  • test2 (diretório)
  • test3 (diretório)

Se você digitar mv *algo aparentemente estranho, acontece: test3existe, mas o resto se foi. Embora estranho no começo, faz sentido quando você entende o que o bash realmente passa mv. Por causa do asterisco, o bash interpreta mv *como mv test test1 test2 test3e, quando mv obtém essa lista, assume-se que o último argumento é o destino, que é onde todos os arquivos teriam sido movidos.

Quanto aos comandos que você listou:

  • echo *pode funcionar como um homem pobre ls. O shell expandirá o asterisco para o que estiver nesse diretório e, como tenho certeza de que você já sabe, echoliteralmente ecoará qualquer coisa que o bash passar a ele como argumentos.
  • cp temp temp*terá um comportamento semelhante ao mvcomando que descrevi acima, a menos que haja apenas um diretório chamado temp; nesse caso, o nome de origem e destino é o mesmo, ou seja, não fará nada.
Jarmund
fonte
8
Não há nada de "ruim" em usar em *vez de ls. Por exemplo, for f in *; doé mais confiável do que for f in $(ls)se um nome de arquivo contiver espaço em branco ou caractere glob. (Será, no entanto, falhar se não houver arquivos na CWD, então você precisa verificar para esse caso.)
rici
11
@rici É para isso que shopt nullglobserve.
um CVn
3
Quanto a echo *, esse truque pode salvar você em alguns casos.
um CVn
2
Fazendo o chiming com: arquivos anexados com "-" em pastas arbitrárias que acionam opções indesejáveis. Removê-los não é muito divertido até você perceber que o arquivo rm ./-stupid funciona.
ǝɲǝɲbρɯͽ
11
@ ǝɲǝɲbρɯͽ Notei quando certa vez precisei excluir o conteúdo de um diretório que continha arquivos com o nome do arquivo representando posições em um sistema de coordenadas, de -1024x-1024 a 1024x1024. Foi quando eu aprendi sobre como fugir.
Jarmund #
5

Como já foi dito, o shell se expande *para echoreceber como argumentos o que o shell encontrar no diretório atual. No entanto, observe que, se a expansão não resultar em nada, ou seja, nesse caso, se o diretório não contiver arquivos não ocultos, ele *permanecerá inalterado e transmitido como está para o comando chamado (a menos que opções não padrão sejam usadas com alguns shells como bash). echo *não vai se comportar como um homem pobre, lspois o primeiro não imprime nada enquanto o segundo imprime *.

Da mesma forma, cp /tmp/temp temp*criará um arquivo nomeado temp*no diretório atual se ainda não houver pelo menos um arquivo com o qual o nome comece temp.

Por fim, se você deseja que a *transmissão seja inalterada, seja qual for o caso, é possível protegê-lo da expansão usando aspas simples '*', aspas duplas "*"ou barra invertida \*.

jlliagre
fonte
4

No Bash, o shell lida com isso. Você vê que, se você tentar *sem eco

Nota: com base em alguns comentários, sugiro que, ao executar * ENTER, crie um diretório e use o comando touch para criar alguns arquivos e verifique se nenhum deles, ou pelo menos verifique se o primeiro em ordem alfabética não é o nome de qualquer script ou comando no caminho.

$ *
bash: a: command not found

$ echo *
a a.aa a.ab a.b a.htm a.tx

Então ls *é um pouco de clichê

No Windows, *é tratado pelo comando, portanto, dir *.*não é um clichê.

Nota- Vendo alguns comentários, eu acrescentaria, há um risco correndo * e depois ENTER. Se você tem um arquivo chamado rm, o primeiro na lista de diretórios, é perigoso porque qualquer coisa após a exclusão será excluída. Além disso, e isso é menos improvável, se o primeiro arquivo na lista de diretórios for o nome de um script no caminho, ele será executado.

barlop
fonte
4
Observe que pode haver um arquivo chamado rm, é claro.
Volker Siegel
11
... e um outro chamado rf
ǝɲǝɲbρɯͽ
11
@ ǝɲǝɲbρɯͽ você pode ter um arquivo cujo nome de arquivo é -rf? Eu tentei touch -rfe touch \-rfmas não está criando.
barlop
@ Barlop comentei acima; o gui (como o gedit) lida com eles muito bem, mas como o shell (pelo menos o bash) passa isso por ele requer ./ na frente. Se você criar um arquivo acidentalmente, o rm tenta sugerir, mas se não o fizer: espero que isso acabe em uma pasta temporária com filhos descartáveis.
ǝɲǝɲbρɯͽ
@ ǝɲǝɲbρɯͽ Eu não entendo o que quer dizer em tudo, eu estou perguntando como você pode criar um arquivo que é chamado -rf? (Eu entendo o perigo de um arquivo chamado rm e um arquivo chamado -rf, eo problema de digitação * e empurrando entrar em uma pasta importante, eu não planejo fazer isso)
barlop
-1

O shell executa várias expansões antes que os argumentos sejam entregues ao comando.

Veja também https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

Não é específico do bash, consulte http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01

Glenn Jackman
fonte
Tecnicamente, o que você está escrevendo está correto, mas sem os links, essa resposta realmente não faz nada para responder à pergunta. Considere incorporar os detalhes relevantes.
um CVn
@ MichaelKjörling Eu concordo com o assunto sobre os links, mas o OP simplesmente perguntou se o shell ou o próprio comando lidava com os argumentos. A resposta de Glenn simplesmente afirma que o shell lida com eles, portanto é uma resposta aceitável para a pergunta.
slhck
@slhck É por isso que não sinalizei como NAA: ainda resta algo que aborda a questão depois de remover os links. Isso não significa que esta seja uma boa resposta para mim . (Agora vejo que o meu comentário inicial poderia ser interpretado de outra forma, por isso, peço desculpas, mas eu ainda acho que tem valor suficiente para deixá-lo onde está.)
um CVn
@ MichaelKjörling concordou. Acabei de deixar o comentário para quem fez (e vai) sinalizar como NAA.
slhck