“read” funciona como esperado no ZSH, mas se comporta de maneira diferente ao usar qualquer outro shell

1

Eu escrevi um pequeno ciclo while - do , mas achei que estava funcionando de forma estranha com diferentes camadas.

É isso aí:

find "'pwd'" -type d | while read -r D; do ls ${D}; done

Quando eu inicio usando zsh , tudo fica legal. No entanto, usando qualquer outro shell ele quebra quando eu inicio em qualquer diretório com caracteres de escape no título.

Por que isso acontece? Eu tentei jogar com read -d , mas ele ignora qualquer tipo de caractere de escape como \ n. read -r também não faz nada.

    
por mokrinsky 30.08.2015 / 00:35

2 respostas

1

Tente isto: find "$(pwd)" -type d | while read -r D; do ls -lb "${D}"; done

Com apenas ls , tudo o que você verá no bash é um ? para um nome de arquivo igual a "\ n".
Além disso, -print0 | xarg -0 pode ser necessário nesses casos, e um $D sem aspas, quando $ D contiver espaço em branco, provavelmente causará problemas.

$ man ls excerpt:

-b, --escape
      print C-style escapes for nongraphic characters
-l    use a long listing format

O material imprudente:
Exemplo: $ rm "$(echo -en "\r")" - permite a remoção de um arquivo com um único retorno de carro (CR) como nome.

E, claro, se você quiser mexer com isso:
$ echo "TEST" >"This is a filename with a CR _$(echo -en "\r")_here"
... cria um arquivo.

$ rm "This is a filename with a CR _$(echo -en "\r")_here"
... para removê-lo.

    
por 30.08.2015 / 05:07
0

Why is that so?

${D} é o mesmo que $D . Ele será substituído pelo shell pelo conteúdo da variável D . Então, se D contiver Hello World , seu

ls -lb $D

torna-se

ls -lb Hello World

que tentará listar os dois diretórios Hello e World (em vez do diretório 1 Hello World ).

Scott já forneceu a maneira correta: use "$D" , o que resultará em

ls -lb "Hello World"
    
por 01.09.2015 / 22:14