Dlaczego „ls” nagle owija przedmioty spacjami w pojedyncze cudzysłowy?

187

Właśnie zauważyłem, że na jednym z moich komputerów (z uruchomionym Debianem Sid) zawsze, gdy wpisuję lsdowolną nazwę pliku ze spacjami, otaczają ją pojedyncze cudzysłowy.

Natychmiast sprawdziłem swoje aliasy, ale znalazłem je nietknięte.

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$

(obrazek)

Kolejny test z plikami zawierającymi pojedyncze cudzysłowy w ich nazwach (również odpowiadające na prośbę 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'

(obrazek)

aktualizacja z nowym wyjściem coreutils-8.26 (co jest wprawdzie o wiele mniej mylące, ale irytujące, że domyślnie). Dzięki Pádraig Brady za ten wydruk:

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

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

Dlaczego to się dzieje? Jak mam to właściwie zatrzymać?

dla wyjaśnienia, sam ustawiłem ls na automatyczne drukowanie w kolorze. Nigdy wcześniej nie wstawiał cytatów.

Jestem uruchomiony bashi coreutils 8.25.

EDYCJA: Wydaje się, że programiści Coreutils myśleli (link) , że dobrym pomysłem byłoby uczynienie tego globalnym domyślnym, pomimo złamania zasady najmniejszego zdziwienia, a także ponad 46 lat tradycji UNIX.

Jakiś sposób to naprawić bez ponownej kompilacji?


AKTUALIZACJA - październik 2017 r. - Debian Sid ponownie domyślnie włączył cytowanie ucieczki powłoki. To staje się po prostu śmieszne. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

A u dołu łańcucha odpowiedzi na poprzedni raport o błędzie „zmiana była zamierzona i pozostanie”. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

Myślałem, że to załatwione. Najwyraźniej nie.

AKTUALIZACJA: kwiecień 2019: Właśnie znalazłem luksusowy raport o błędach w PHP, który został spowodowany przez tę zmianę w ls. Kiedy mylisz programistów i generujesz fałszywe raporty o błędach, nadszedł czas, aby przemyśleć swoje zmiany.

Aktualizacja: Android toybox lsrobi teraz coś podobnego do tego, ale z cudzysłowami zamiast cudzysłowów. Użycie opcji -q powoduje, że spacje są renderowane jako „znaki zapytania” (nie sprawdziłem, co to są, ponieważ oczywiście nie są spacjami), więc jedyną poprawką, jaką znalazłem do tej pory bez rootowania danego urządzenia, jest dodanie to do skryptu i źródło podczas uruchamiania powłoki. Ta funkcja lskorzysta z kolumn, jeśli jest w terminalu, i w inny sposób drukuje jeden na wiersz, jednocześnie wnikając lsdo spacji drukowanych dosłownie, ponieważ biegnie przez potok.

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
źródło
20
To kolejny powód, dla którego nie przeanalizujesz lspolecenia.
jimmij
12
Wygląda to dziwnie, ale jeśli jest włączone tylko podczas drukowania na terminalu, ma sens. Widać wyraźnie, że masz plik „test 1.txt” zamiast pliku „test” i inny „1.txt”. Spróbuj ls | cati zobacz, czy to zniknie. Gdybym miał maszynę czasu, wróciłbym do Bell Labs ~ 1970 i próbował przekonać Kena Thompsona, że ​​dopuszczanie miejsca w nazwach plików i katalogów to zły pomysł. :-P
Bjorn Munch
6
Kiedy zobaczyłem to po raz pierwszy, wystraszyłem się, myśląc, że jeden z moich skryptów nie działa i zmieniłem nazwę wszystkich plików na '*'. Chyba się lsrozejrzę, dodając pseudonimy do wszystkich moich maszyn, aby się ich pozbyć ...
Ograniczone Zadośćuczynienie
14
@LimitedAtonement, jak zauważył Lekensteyn , możesz to zrobić za pomocą zmiennej środowiskowej QUOTING_STYLE=literalzamiast aliasu. (Myślę, że to kwestia gustu, ale wolę zmienną.)
LSpice
4
@BjornMunch istnieją dwa rozwiązania problemu polegającego na określeniu, czy jest to jeden plik, czy dwa: 1) poszukaj sposobu rysowania kolumn i jest to dość oczywiste. 2) wymień jedną pozycję w wierszu. Oba wyglądają lepiej i wyraźniej niż mieszanie się z pojedynczymi cudzysłowami.
Wyatt8740

Odpowiedzi:

132

Przedmowa : Chociaż głosowanie nad odpowiedzią taką jak ta i nazwanie jej dniem może być całkiem satysfakcjonujące, zapewniamy, że programiści GNU nie dbają o głosy SO, a jeśli naprawdę chcesz zachęcić ich do zmiany , musisz: wyślij im e-mailem, jak opisuje ta odpowiedź.


Dlaczego tak się dzieje?

Kilku programistów Coreutils zdecydowało, że znają więcej niż dekady faktycznych standardów.


Jak to właściwie zatrzymać?

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

Zgłaszanie błędów

Jeśli uważasz, że znalazłeś błąd w Coreutils, prześlij jak najdokładniejszy raport o błędzie na adres <[email protected]> , a zostanie on automatycznie wpisany do narzędzia do śledzenia błędów Coreutils. Przed zgłoszeniem błędów przeczytaj FAQ. Bardzo przydatnym i często przywoływanym przewodnikiem na temat pisania raportów o błędach i zadawania dobrych pytań jest dokument Jak zadawać pytania w inteligentny sposób. Możesz przeglądać poprzednie posty i przeszukiwać archiwum bug-coreutils.

Dystrybucje, które zostały już przywrócone  tę zmianę:

  • Debian coreutils-8.25-2
    • W tym prawdopodobnie Ubuntu i wszystkie setki pochodnych Debiana i Ubuntu

Zakłócenia nie ulegają zmianie:

  • openSUSE (już używany -N)

Jakiś sposób to naprawić bez ponownej kompilacji?

Zwolennicy chcieliby, żebyś ...

wróć do starego formatu, dodając -N do aliasu ls

… Na wszystkich twoich instalacjach, wszędzie, przez resztę wieczności.

Jan Kyu Peblik
źródło
17
Zmiana została zaproponowana na liście mailingowej i uzgodniona przez trzech głównych opiekunów programu jako korzyść netto. Jesteśmy całkowicie otwarci na konstruktywne argumenty na ten temat. W końcu jest to oprogramowanie typu open source, nie mamy na celu dyktowania, a jedynie ulepszenia. Zachęcamy do odpowiedzi w wątku coreutils na lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (przy okazji, konstruktywna sugestia, aby poprawić jedną z wymienionych tu wad estetycznych, przez dodanie spacji w celu poprawy wyrównania)
Pádraig Brady
31
@ PádraigBrady Zaktualizowana odpowiedź. Widzę jednak wiele odmów w twoim wątku coreutils. Najważniejsze jest to, że tworzysz więcej pracy dla ludzi i robisz to w imieniu systemu operacyjnego, który jest klonem systemu operacyjnego z 1970 roku. Jeśli ludzie chcą czegoś innego, zdecydują się na to.
Jan Kyu Peblik
43
@ PádraigBrady Ta zmiana wywołała u mnie irytację i zmarnowałem kilka godzin na szukanie przyczyny i rozwiązania. Nie chcę być negatywny - po prostu dzielę punkt widzenia innej osoby! Modyfikacja zachowania rdzenia ma ogromne konsekwencje.
mafroza
52
Jako ktoś, kto korzysta z systemów * nix od 30 lat, uważam, że takie nieuzasadnione zmiany są dość denerwujące. Po pierwsze łamią dawne skrypty. Naruszają także zasadę najmniejszego zdziwienia. Jak wspomniano powyżej, „Opt-in” powinno być tutaj domyślne.
Brian Clapper,
28
@ PádraigBrady Nadal nie jest to sposób na wprowadzenie takich zmian. Mogłoby być sposób bardziej konstruktywny mieć to zachowanie opt-in zamiast domyślnie aktywne. Fałszywie sugeruje również, w jaki sposób są przechowywane nazwy plików, krótko mówiąc, lsto, czego już nie widać, to sposób ich przechowywania. Ta funkcja powinna być opcjonalna, a nie domyślna.
91

Możesz wybrać styl cytowania :

ls --quoting-style=literal

Taki sam jak:

ls -N

lub:

QUOTING_STYLE=literal ls

Ustaw go jako alias lub ustaw export QUOTING_STYLE=literalw swoim, .bashrcaby osiągnąć zachowanie sprzed 8.25.

Cuonglm
źródło
11
wydaje się trochę dziwne. Muszę to zrobić, aby uzyskać normalne zachowanie uniksowe. Chcę też starego domyślnego. Nie sądzę, że ucieczka była starym domyślnym - myślę, że wydrukowała dokładnie to, co faktycznie tam było.
Wyatt8740,
9
Dla zachowania sprzed 8.25 użyj export QUOTING_STYLE=literalw swoim bashrc.
Lekensteyn
2
lub użyj -N, jak się wydaje. Właśnie kompiluję własną wersję, ponieważ mam już skonfigurowane osobiste repozytorium.
Wyatt8740
2
@LSpice Mam edytowany post do użycia literalzamiast escape(wierzę, że @cuonglm prostu chciał pokazać, jak zmienić styl, nie specjalnie targetting ten escapestyl).
Lekensteyn
5
Ta odpowiedź zasługuje na więcej pochwał. Odpowiada wprost na pytania zadane przez pytającego, unikając biurokratycznej odpowiedzi. Rzeczywiście podejście do zmiennych środowiskowych wydaje się dość eleganckie. (Osobiście wolę nowe zachowanie, ponieważ faworyzuje bardziej wydajną akcję C&P), ale ls jest wystarczająco sprytny, aby zachowywać się w stary sposób, gdy używane jest przekierowanie, więc nie szkodzi skryptom korzystającym z danych wyjściowych ls.
Marcelo
42

Kilka punktów na temat zmiany.

  • Został wprowadzony w Coreutils v8.25, a wyrównanie poprawione w v8.26
  • Dzieje się tak tylko podczas wysyłania do terminali, więc nie psuje skryptów
  • Ujednoznacznia dane wyjściowe dla użytkowników dla plików zawierających białe znaki
  • Odkaża wydruk, dzięki czemu można go bezpiecznie kopiować i wklejać
  • Wyjście jest teraz zawsze poprawne, aby skopiować i wkleić z powrotem do powłoki
  • Użytkownicy mogą wrócić do starego formatu, dodając -N do swojego aliasu ls
Pádraig Brady
źródło
7
mój ostatni przykład nie jest dwuznaczny? Być może nie - ale z pewnością jest to mylące i zajmuje więcej czasu na rozszyfrowanie. Myślę, że to okropna zmiana (bez obrazy dla ciebie). Dziękuję za alias.
Wyatt8740,
27
Uwaga: ta zmiana została wprowadzona w Coreutils 8.25 ( zatwierdzenie , autorstwa tego samego Pádraiga co ten post). Osobiście uważam, że to zachowanie nie jest optymalne, przerywa wyrównanie za każdym razem, gdy w nazwie pliku występuje spacja.
Lekensteyn
10
przepraszam - najwyraźniej bezpiecznie cytujesz przynajmniej cytaty z muszli. nadal mi się nie podoba. opcje są w porządku - ale zmiana bardzo dobrze określonego domyślnego zachowania dziesięcioletniego narzędzia uniksowego w taki sposób, że zmniejsza jego prawdziwość, może być tylko złym pomysłem.
mikeserv
12
@ PádraigBrady Więc zamierzasz się lszłamać? Spójrz na te wszystkie argumenty przeciwko twojej zmianie. Nikt tego nie chce. Być może czas przeprosić świat i go cofnąć.
Chris Warrick
6
@ PádraigBrady Więc pomimo wielu osób, które wyjaśniły, jak to jest źle, zepsute itp., Nadal nie cofniesz tego, aby domyślna wartość nie uległa zmianie? W przeciwieństwie do twojego przekonania, ta zmiana wprowadza w błąd, nie jednoznacznie. Sugerowanie, że ludzie ustawiają zmienną środowiskową lub alias, jest co najwyżej asinine.
Mark