Почему 'ls' внезапно заключает элементы в одинарные кавычки?

187

Я только что заметил, что на одном из моих компьютеров (на котором запущен Debian Sid) всякий раз, когда я lsнабираю имя файла с пробелами, его заключают в одинарные кавычки.

Я немедленно проверил свои псевдонимы, чтобы найти их нетронутыми.

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$

(рисунок)

Другой тест, с файлами, содержащими одинарные кавычки в своих именах (также отвечая на запрос 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'

(рисунок)

обновление с новым выходом coreutils-8.26 (который, по общему признанию, гораздо менее запутан, но по-прежнему раздражает иметь по умолчанию). Спасибо Pádraig Brady за эту распечатку:

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

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

Почему это происходит? Как мне остановить это правильно?

чтобы уточнить, я сам установил ls для автоматического вывода цвета. Это никогда не помещало кавычки вокруг вещей прежде.

Я бегу bashи coreutils 8.25.

РЕДАКТИРОВАТЬ: Похоже, разработчики coreutils думали (ссылка), что было бы хорошей идеей сделать это глобальным дефолтом, несмотря на нарушение принципа наименьшего удивления, а также более чем 46-летней традиции UNIX.

Любой способ исправить это без перекомпиляции?


ОБНОВЛЕНИЕ - октябрь 2017 г. - Debian Sid по умолчанию снова включил экранирование оболочки. Это просто смешно. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

И в нижней части цепочки ответов на предыдущий отчет об ошибках «изменение было преднамеренным и останется». https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

Я думал, что это было решено. Очевидно нет.

ОБНОВЛЕНИЕ: апрель 2019 г .: только что обнаружен внушительный отчет об ошибках в PHP, вызванный этим изменением ls. Когда вы сбиваете с толку разработчиков и генерируете ложные сообщения об ошибках, пришло время переосмыслить ваши изменения.

Обновление: Android toybox lsтеперь делает нечто похожее на это, но с обратными слешами вместо кавычек. При использовании опции -q пробелы отображаются как «символы вопросительного знака» (я не проверял, какие они есть, поскольку они, очевидно, не пробелы), поэтому единственное исправление, которое я нашел до сих пор без рутирования рассматриваемого устройства, это добавить это в сценарий и источник его при запуске оболочки. Эта функция позволяет lsиспользовать столбцы, если они находятся в терминале и, в противном случае, печатают по одной на строку, одновременно вводя lsв заблуждение пространство печати, поскольку оно проходит через трубу.

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
источник
20
Еще одна причина, почему бы не анализировать lsкоманду.
Джимми
12
Это выглядит странно, но если оно включено только при печати на терминал, это имеет смысл. Вы можете ясно видеть, что у вас есть файл «test 1.txt», а не файл «test» и другой «1.txt». Попробуйте ls | catи посмотрите, исчезнет ли это. Если бы у меня была машина времени, я бы вернулся к Bell Labs ~ 1970 и попытался бы убедить Кена Томпсона в том, что выделение места в именах файлов и каталогов - плохая идея. :-P
Бьорн Мунк
6
Когда я впервые увидел это, я испугался, думая, что один из моих сценариев испортился и переименовал все мои файлы '*'. Я думаю, что я буду добавлять lsпсевдонимы ко всем моим машинам, чтобы избавиться от них ...
Ограниченное искупление
14
@LimitedAtonement, как указал Лекенштейн , вы можете сделать это с помощью переменной окружения, QUOTING_STYLE=literalа не псевдонима. (Я думаю, это дело вкуса, но я предпочитаю переменную.)
LSpice
4
@BjornMunch есть два решения вопроса о том, является ли это одним файлом или двумя: 1) посмотрите, как отображаются столбцы, и это довольно очевидно. 2) перечислить один элемент в строке. Оба из них выглядят лучше и понятнее, чем искажение в одинарных кавычках.
Wyatt8740

Ответы:

132

Предисловие : Несмотря на то, что может быть весьма удовлетворительным объявить ответ, подобный этому, и назвать его днем, пожалуйста, будьте уверены, что разработчики GNU не заботятся о SO голосах за ответы, и что, если вы действительно хотите побудить их измениться , вам необходимо напишите им, как этот ответ описывает.


" Почему это происходит? "

Несколько разработчиков Coreutils решили, что они знают лучше, чем десятилетия стандартов де-факто.


" Как мне остановить это правильно? "

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

Отчеты об ошибках

Если вы считаете, что обнаружили ошибку в Coreutils, отправьте как можно более полный отчет об ошибке по адресу <bug-coreutils@gnu.org> , и он автоматически будет добавлен в систему отслеживания ошибок Coreutils. Прежде чем сообщать об ошибках, пожалуйста, прочитайте FAQ. Очень полезным и часто упоминаемым руководством о том, как писать отчеты об ошибках и задавать хорошие вопросы, является документ «Как задавать вопросы умным путем». Вы можете просматривать предыдущие публикации и искать в архиве bug-coreutils.

Дистрибутивы , которые уже Откачены  это изменение:

Дистрибутивы не затронуты:

  • openSUSE (уже используется -N)

" Любой способ исправить это без перекомпиляции? "

Сторонники бы вы ...

вернуться к старому формату, добавив -N к псевдониму ls

... во всех ваших инсталляциях, везде, до конца вечности.

Ян Кью Пеблик
источник
17
Изменение было предложено в списке рассылки и было согласовано тремя сопровождающими coreutils как чистая выгода. Мы полностью открыты для конструктивных аргументов по этому поводу. В конце концов, это открытый исходный код, мы не хотим диктовать, только улучшать вещи. Пожалуйста, не стесняйтесь отвечать в ветке coreutils на lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (кстати, было конструктивное предложение по улучшению одного из упомянутых здесь эстетических недостатков, добавив пробел для улучшения выравнивания)
Pádraig Brady
31
@ PádraigBrady Обновленный ответ. Однако, вы видите множество отрицаний в вашей ветке coreutils. Суть в том, что вы создаете больше работы для людей, и вы делаете это во имя ОС, которая является клоном ОС 1970 года. Если люди хотят чего-то другого, они выберут это.
Ян Кью Пеблик
43
@ PádraigBrady Это изменение вызвало у меня раздражение и потратило несколько часов на поиски причины и решения. Я не хочу быть негативным - я просто разделяю точку зрения других людей! Изменение основного поведения имеет огромное значение ..
Mafrosis
52
Как человек, который использует * nix системы в течение 30 лет, я нахожу такие беспричинные изменения довольно раздражающими. Они ломают давние сценарии, с одной стороны. Они также нарушают принцип наименьшего удивления. «Отказ» должен был быть по умолчанию здесь, как отмечено выше.
Брайан Клаппер
28
@ PádraigBrady Это еще не способ подтолкнуть такие изменения. Это был бы путь более конструктивным , чтобы это поведение неавтоматического вместо активной по умолчанию. Это также ложно намекает на то, как хранятся имена файлов, короче говоря, lsто, что вы видите, больше не хранится. Эта функция должна быть необязательной, а не по умолчанию.
91

Вы можете выбрать стиль цитирования :

ls --quoting-style=literal

Такой же как:

ls -N

или же:

QUOTING_STYLE=literal ls

Сделать это псевдоним, или установить export QUOTING_STYLE=literalв вашем .bashrcдостичь заранее 8.25 поведения.

cuonglm
источник
11
кажется немного странным, я должен сделать это, чтобы получить нормальное поведение Unix-Y. Кроме того, я хочу старый по умолчанию. Я не думаю, что побег был старым по умолчанию - я думаю, что он напечатал именно то, что было на самом деле.
Wyatt8740
9
Для поведения до 8.25, используйте export QUOTING_STYLE=literalв вашем bashrc.
Лекенштейн
2
или использовать -N, кажется. Я просто собираю свою собственную версию, так как у меня уже есть настроенный личный репозиторий.
Wyatt8740
2
@LSpice Я отредактировал пост, чтобы использовать literalвместо него escape(я считаю, что @cuonglm просто хотел показать, как изменить стиль, не ориентируясь конкретно на escapeстиль).
Лекенштейн
5
Этот ответ заслуживает большего количества голосов. Это прямо касается того, что спросил спрашивающий, избегая бюрократического ответа. Действительно, подход с использованием переменных среды выглядит довольно элегантно. (Я лично предпочитаю новое поведение, так как оно способствует более эффективному действию C & P), однако, ls достаточно умен, чтобы вести себя по-старому, когда используется перенаправление, поэтому не повредит сценариям, использующим вывод ls.
Марсело
42

Несколько моментов об изменении.

  • Он был представлен в coreutils v8.25, а выравнивание улучшено в v8.26
  • Это происходит только при выводе на терминалы, поэтому не нарушает скрипты
  • Он устраняет неоднозначность вывода для пользователей для файлов, содержащих пробелы
  • Он дезинфицирует выход , так что безопасно копировать и вставлять
  • Вывод теперь всегда действителен для копирования и вставки обратно в оболочку
  • Пользователи могут вернуться к старому формату, добавив -N к своему псевдониму ls.
Падрейг Брейди
источник
7
мой последний пример не является двусмысленным? Возможно нет - но это, безусловно, сбивает с толку и требует больше времени, чтобы расшифровать. Я думаю, что это ужасное изменение (без обид, предназначенных для вас). Спасибо за подсказку псевдонима, хотя.
Wyatt8740
27
Примечание: это изменение было введено в coreutils 8.25 ( коммит , автором которого является тот же Падрейг, что и в этом посте). Лично я думаю, что это поведение неоптимально, оно нарушает выравнивание всякий раз, когда в имени файла появляется пробел.
Лекенштейн
10
Приношу свои извинения - по-видимому, вы, как минимум, безопасно цитируете shell-цитаты. Мне все еще не нравится это. варианты хороши - но изменение очень хорошо определенного поведения по умолчанию десятилетней базовой утилиты Unix таким способом, который уменьшает ее правдивость, может быть только плохой идеей.
mikeserv
12
@ PádraigBrady Итак, ты будешь lsсломлен? Посмотрите на все эти аргументы против вашей перемены. Никто не хочет этого. Возможно, пришло время извиниться перед миром и отменить его.
Крис Уоррик
6
@ PádraigBrady Итак, несмотря на множество людей, которые объяснили, как это неправильно, сломано и т. Д., Вы все равно не вернете это так, чтобы значение по умолчанию не изменилось? Вопреки вашему убеждению, это изменение смущает, а не устраняет неоднозначности. Предполагать, что люди устанавливают переменную окружения или псевдоним, в лучшем случае асининовые.
Марк