Por que 'ls' quebra subitamente itens com espaços entre aspas simples?

187

Acabei de notar que em uma das minhas máquinas (executando o Debian Sid) sempre que digito lsqualquer nome de arquivo com espaços, há aspas simples.

Eu verifiquei imediatamente meus apelidos, apenas para encontrá-los intactos.

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt
wyatt@debian630:~/testdir$ alias
alias ls='ls --color=auto'
alias wget='wget --content-disposition'
wyatt@debian630:~/testdir$

(cenário)

Outro teste, com arquivos contendo aspas simples em seus nomes (também respondendo a uma solicitação de jimmij):

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt  'thishasasinglequotehere'\''.txt'
wyatt@debian630:~/testdir$ touch "'test 1.txt'"
wyatt@debian630:~/testdir$ ls
''\''test 1.txt'\'''  test1.txt
'test 1.txt'          'thishasasinglequotehere'\''.txt'

(cenário)

atualize com a nova saída coreutils-8.26 (que é reconhecidamente muito menos confusa, mas ainda assim irritante por padrão). Agradecimentos a Pádraig Brady por esta impressão:

$ ls
"'test 1.txt'"   test1.txt
'test 1.txt'    "thishasasinglequotehere'.txt"

$ ls -N
'test 1.txt'  test1.txt
test 1.txt    thishasasinglequotehere'.txt

Por que isso está acontecendo? Como faço para parar corretamente?

para esclarecer, eu próprio defino ls para colorir automaticamente a saída. Nunca colocou aspas em torno das coisas antes.

Estou executando bashe coreutils 8.25.

EDIT: Parece que os desenvolvedores do coreutils pensaram (link) que seria uma boa idéia tornar esse padrão global, apesar de quebrar o princípio de menor espanto e mais de 46 anos de tradição UNIX.

Alguma maneira de corrigir isso sem recompilar?


ATUALIZAÇÃO - outubro de 2017 - O Debian Sid reativou a citação de escape do shell por padrão. Isso está ficando ridículo. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

E na parte inferior da cadeia de respostas do relatório de erros anterior, "a mudança foi intencional e permanecerá". https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

Eu pensei que isso estava resolvido. Aparentemente não.

ATUALIZAÇÃO: abril de 2019: Acabei de encontrar um relatório de erro supurativo no PHP que foi causado por essa alteração no ls. Quando você está confundindo os desenvolvedores e gerando relatórios de erros falsos, é hora de repensar suas alterações.

Atualização: a caixa de brinquedos Android lsagora está fazendo algo semelhante a isso, mas com barras invertidas em vez de aspas. O uso da opção -q torna os espaços renderizados como 'caracteres de ponto de interrogação' (não verifiquei o que são, pois obviamente não são espaços); portanto, a única correção que encontrei até agora sem fazer o root do dispositivo em questão é adicionar isso para um script e origine-o ao iniciar um shell. Essa função lsutiliza colunas se estiver em um terminal e, caso contrário, imprime uma por linha, enquanto engana os lsespaços de impressão literalmente porque está passando por um tubo.

ls() {
    # only way I can stop ls from escaping with backslashes
    if [ -t 1 ]; then
        /system/bin/ls -C "$@" |cat
    else
        /system/bin/ls "$@" |cat
    fi
}
Wyatt8740
fonte
20
Mais uma razão para não analisar o lscomando.
jimmij
12
Parece estranho, mas se estiver ativado apenas ao imprimir em um terminal, faz sentido. Você pode ver claramente que possui um arquivo 'test 1.txt' em vez de um arquivo 'test' e outro '1.txt'. Tente ls | cate veja se desaparece. Se eu tivesse uma máquina do tempo, voltaria ao Bell Labs ~ 1970 e tentaria convencer Ken Thompson que permitir espaço nos nomes de arquivos e diretórios é uma má idéia. :-P
Bjorn Munch
6
Quando vi isso pela primeira vez, fiquei apavorada, pensando que um dos meus scripts tinha dado errado e renomeei todos os meus arquivos para '*'. Eu acho que vou por aí adicionando lsaliases em todas as minhas máquinas para me livrar dele ...
Expiação Limitada
14
@LimitedAtonement, como apontado por Lekensteyn , você pode fazer isso com uma variável de ambiente QUOTING_STYLE=literale não com um alias. (Eu acho que é uma questão de gosto, mas eu prefiro a variável.)
LSpice
4
@BjornMunch, existem duas soluções para a questão de saber se é um ou dois arquivos: 1) procure como as colunas estão sendo desenhadas e isso é bastante óbvio. 2) liste um item por linha. Os dois parecem melhores e mais claros do que os que aparecem com aspas simples.
Wyatt8740

Respostas:

132

Prefácio : Embora possa ser bastante satisfatório aprovar uma resposta como essa e chamá-la um dia, tenha certeza de que os desenvolvedores do GNU não se importam com os votos de resposta SO, e que, se você realmente deseja incentivá-los a mudar , precisa envie-os por e-mail como esta resposta descreve.


" Por que isso está acontecendo? "

Vários desenvolvedores de coreutils decidiram que conheciam melhor que décadas de padrões de fato.


" Como eu paro isso corretamente? "

http://www.gnu.org/software/coreutils/coreutils.html :

Relatório de erros

Se você acha que encontrou um bug no Coreutils, envie um relatório de bug o mais completo possível para <[email protected]> , e ele será automaticamente inserido no rastreador de erros do Coreutils. Antes de relatar erros, leia as Perguntas frequentes. Um guia muito útil e frequentemente referenciado sobre como escrever relatórios de bugs e fazer boas perguntas é o documento Como fazer perguntas de maneira inteligente. Você pode navegar pelas postagens anteriores e pesquisar no arquivo bug-coreutils.

Distros que já reverteram  essa alteração:

Distros não afetados:

  • openSUSE (já usado -N)

" Alguma maneira de corrigir isso sem recompilar? "

Os proponentes queriam você ...

volte ao formato antigo adicionando -N ao seu alias ls

... em todas as suas instalações, em qualquer lugar, pelo resto da eternidade.

Jan Kyu Peblik
fonte
17
A alteração foi proposta na lista de discussão e acordada por três mantenedores do coreutils como um benefício líquido. Estamos totalmente abertos a argumentos construtivos sobre isso. Afinal, este é um código aberto, não queremos ditar, apenas melhorar as coisas. Sinta-se à vontade para responder no tópico coreutils em lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (a propósito, houve uma sugestão construtiva para melhorar uma das desvantagens estéticas mencionadas ali, adicionando um espaço para melhorar o alinhamento)
Pádraig Brady 15/02
31
@ PádraigBrady Resposta atualizada. Porém, vendo cargas de negação no thread do coreutils. O ponto principal é que você está criando mais trabalho para as pessoas e está fazendo isso em nome de um sistema operacional que é um clone de um sistema operacional de 1970. Se as pessoas querem algo diferente, elas optam por isso.
Jan Kyu Peblik
43
@ PádraigBrady Essa mudança me causou aborrecimento e desperdicei várias horas tentando encontrar uma causa e uma solução. Não quero ser negativo - estou apenas compartilhando o ponto de vista de outras pessoas! Modificar o comportamento do núcleo tem implicações enormes ..
mafrosis
52
Como alguém que usa sistemas * nix há 30 anos, acho que mudanças gratuitas como essa são bastante irritantes. Eles quebram scripts de longa data, por um lado. Eles também violam o princípio da menor surpresa. "Optar por entrar" deveria ter sido o padrão aqui, conforme observado acima.
Brian Clapper
28
@ PádraigBrady Essa ainda não é a maneira de promover essas mudanças. Teria sido muito mais construtivo ter esse comportamento ativado em vez de ativo por padrão. Ele também sugere falsamente que é assim que os nomes dos arquivos são armazenados, em resumo, o lsque você vê não é mais como eles são armazenados. Esse recurso deve ser opcional, não o padrão.
91

Você pode escolher o estilo de citação :

ls --quoting-style=literal

O mesmo que:

ls -N

ou:

QUOTING_STYLE=literal ls

Crie um alias ou configure export QUOTING_STYLE=literal-o .bashrcpara obter um comportamento anterior a 8,25.

cuonglm
fonte
11
parece um pouco estranho eu tenho que fazer isso para obter um comportamento unix-y normal. Além disso, quero o antigo padrão. Eu não acho que escapar era o antigo padrão - acho que imprimiu exatamente o que realmente estava lá.
precisa saber é o seguinte
9
Para um comportamento pré-8,25, use export QUOTING_STYLE=literalno seu bashrc.
Lekensteyn 31/01
2
ou usar -N, ao que parece. Estou apenas compilando minha própria versão, já que já tenho um repositório pessoal configurado.
precisa saber é o seguinte
2
@LSpice Eu editei o post para usá-lo em literalvez de escape(acredito que o @cuonglm só queria mostrar como mudar o estilo, não visando especificamente o escapeestilo).
Lekensteyn
5
Esta resposta merece mais votos. Ele aborda diretamente o que o interlocutor pediu, evitando uma resposta burocrática. De fato, a abordagem de variável de ambiente parece bastante elegante. (Eu, pessoalmente, prefiro o novo comportamento, pois favorece uma ação C&P mais eficiente). No entanto, ls é inteligente o suficiente para se comportar da maneira antiga quando um redirecionamento é usado, portanto, nenhum dano aos scripts que usam a saída de ls.
Marcelo
42

Alguns pontos sobre a mudança.

  • Foi introduzido no coreutils v8.25 e o alinhamento foi aprimorado na v8.26
  • Isso só acontece ao enviar para terminais, para não quebrar scripts
  • Desambigua a saída dos usuários para arquivos que contêm espaço em branco
  • Ele higieniza a saída para que seja seguro copiar e colar
  • A saída agora é sempre válida para copiar e colar de volta ao shell
  • Os usuários podem voltar ao formato antigo adicionando -N ao seu alias ls
Pádraig Brady
fonte
7
meu último exemplo não é ambíguo? Talvez não - mas é certamente confuso e leva mais tempo para decifrar. Eu acho que é uma mudança terrível (sem ofensa destinada a você). Obrigado pela dica de apelido embora.
precisa saber é o seguinte
27
Nota: esta alteração foi introduzida no coreutils 8.25 ( commit , de autoria do mesmo Pádraig que este post). Pessoalmente, acho que esse comportamento é subótimo, ele quebra o alinhamento sempre que ocorre um espaço em um nome de arquivo.
Lekensteyn 31/01
10
minhas desculpas - aparentemente você está citando com segurança as aspas das conchas pelo menos. eu ainda não gosto disso. as opções são boas - mas alterar o comportamento padrão muito bem especificado de um utilitário núcleo unix de décadas de forma a diminuir sua veracidade pode ser apenas uma idéia.
mikeserv
12
@ PádraigBrady Então, você vai ficar lsquebrado? Veja todos esses argumentos contra sua alteração. Ninguém quer isso. Talvez seja hora de pedir desculpas ao mundo e desfazê-lo.
Chris Warrick
6
@ PádraigBrady Então, apesar das muitas pessoas que explicaram como isso está errado, quebrado, etc, você ainda não reverterá isso para que o padrão não seja alterado? Ao contrário da sua crença, essa mudança não confunde . Sugerir que as pessoas definam uma variável ou alias de ambiente é estético, na melhor das hipóteses.
Mark