Mengapa 'ls' tiba-tiba membungkus barang dengan spasi dalam tanda kutip tunggal?

187

Saya hanya memperhatikan bahwa di salah satu mesin saya (menjalankan Debian Sid) setiap kali saya mengetik lsnama file dengan spasi memiliki tanda kutip tunggal di sekitarnya.

Saya segera memeriksa alias saya, hanya untuk menemukan mereka utuh.

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$

(gambar)

Tes lain, dengan file yang berisi tanda kutip tunggal dalam namanya (juga menjawab permintaan oleh 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'

(gambar)

memperbarui dengan keluaran coreutils-8.26 baru (yang diakui jauh lebih membingungkan, tetapi masih menjengkelkan untuk dimiliki secara default). Terima kasih kepada Pádraig Brady untuk cetakan ini:

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

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

Mengapa ini terjadi? Bagaimana cara menghentikannya dengan benar?

untuk mengklarifikasi, saya sendiri mengatur ls untuk secara otomatis mengeluarkan warna. Itu tidak pernah menempatkan tanda kutip di sekitar hal sebelumnya.

Saya sedang menjalankan bashdan coreutils 8.25.

EDIT: Muncul pikir pengembang coreutils (link) itu akan menjadi ide yang baik untuk membuat default global meskipun melanggar prinsip paling tidak heran serta 46 + tahun tradisi UNIX.

Adakah cara untuk memperbaikinya tanpa kompilasi ulang?


UPDATE - Oktober 2017 - Debian Sid telah mengaktifkan kembali shell escape mengutip secara default. Ini semakin konyol. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

Dan di bagian bawah rantai balasan ke laporan bug sebelumnya, "perubahan itu disengaja dan akan tetap." https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

Saya pikir ini sudah beres. Sepertinya tidak.

UPDATE: April 2019: Baru saja menemukan laporan bug yang luar biasa di PHP yang disebabkan oleh perubahan ini ls. Saat Anda membingungkan pengembang dan membuat laporan bug palsu, inilah saatnya untuk memikirkan kembali perubahan Anda.

Pembaruan: Android toybox lssekarang melakukan sesuatu yang mirip dengan ini tetapi dengan garis miring terbalik bukan tanda kutip. Menggunakan opsi -q menjadikan spasi render sebagai 'karakter tanda tanya' (saya belum memeriksa apa itu, karena jelas bukan spasi), jadi satu-satunya perbaikan yang saya temukan sejauh ini tanpa me-rooting perangkat yang dimaksud adalah menambahkan ini ke skrip dan sumbernya saat meluncurkan shell. Fungsi ini lsmemanfaatkan kolom jika berada di terminal dan mencetak satu per baris, sambil menjebak lske dalam ruang cetak kata demi kata karena berjalan melalui pipa.

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
sumber
20
Namun alasan lain mengapa tidak menguraikan lsperintah.
jimmij
12
Ini terlihat aneh tetapi jika hanya diaktifkan saat mencetak ke terminal, itu masuk akal. Anda dapat melihat dengan jelas bahwa Anda memiliki file 'test 1.txt' daripada file 'test' dan '1.txt' lainnya. Coba ls | catdan lihat apakah itu hilang. Jika saya memiliki mesin waktu, saya akan kembali ke Bell Labs ~ 1970 dan mencoba meyakinkan Ken Thompson bahwa memberi ruang pada nama file dan direktori adalah ide yang buruk. :-P
Bjorn Munch
6
Ketika saya pertama kali melihat ini, saya panik, berpikir bahwa salah satu skrip saya salah dan mengganti nama semua file saya '*'. Saya kira saya akan berkeliling menambahkan lsalias ke semua mesin saya untuk menyingkirkannya ...
Penebusan Terbatas
14
@LimitedAtonement, seperti yang ditunjukkan oleh Lekensteyn , Anda bisa melakukan ini dengan variabel lingkungan QUOTING_STYLE=literaldaripada alias. (Saya kira ini masalah selera, tapi saya lebih suka variabelnya.)
LSpice
4
@BjornMunch ada dua solusi untuk masalah mengatakan apakah itu satu atau dua file: 1) mencari bagaimana kolom sedang digambar dan itu cukup jelas. 2) daftar satu item per baris. Keduanya terlihat lebih baik dan lebih jelas daripada mangling dengan tanda kutip tunggal.
Wyatt8740

Jawaban:

132

Pendahuluan : Walaupun mungkin cukup memuaskan untuk memutakhirkan jawaban seperti ini dan menyebutnya sehari, yakinlah bahwa pengembang GNU tidak peduli dengan suara jawaban SO, & bahwa jika Anda benar-benar ingin mendorong mereka untuk berubah , Anda perlu kirim email kepada mereka sebagaimana dijelaskan oleh jawaban ini.


" Kenapa ini terjadi? "

Beberapa pengembang coreutils memutuskan mereka tahu lebih baik daripada dekade standar de facto.


" Bagaimana cara menghentikannya dengan benar? "

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

Laporan Bug

Jika Anda merasa telah menemukan bug di Coreutils, maka silakan kirim laporan bug selengkap mungkin ke <[email protected]> , dan itu akan secara otomatis dimasukkan ke dalam pelacak bug Coreutils. Sebelum melaporkan bug, harap baca FAQ. Panduan yang sangat berguna dan sering dirujuk tentang cara menulis laporan bug dan mengajukan pertanyaan yang baik adalah dokumen Cara Mengajukan Pertanyaan dengan Cara Cerdas. Anda dapat menelusuri posting sebelumnya dan mencari arsip bug-coreutils.

Distro yang telah mengembalikan  perubahan ini:

Distro tidak terpengaruh:

  • openSUSE (sudah digunakan -N)

" Adakah cara untuk memperbaikinya tanpa kompilasi ulang? "

Pemrakarsa menginginkan Anda ...

kembali ke format lama dengan menambahkan -N ke alias ls mereka

... pada semua instal Anda, di mana saja, selama sisa keabadian.

Jan Kyu Peblik
sumber
17
Perubahan itu diusulkan pada milis dan disetujui oleh tiga pengelola coreutils untuk menjadi keuntungan bersih. Kami sepenuhnya terbuka untuk argumen konstruktif tentang ini. Bagaimanapun, ini adalah open source, kami tidak bermaksud mendikte, hanya untuk memperbaiki keadaan. Silakan merespons di utas coreutils di lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (BTW, ada saran konstruktif untuk memperbaiki salah satu kerugian estetika yang disebutkan di sana, dengan menambahkan spasi untuk meningkatkan perataan)
Pádraig Brady
31
@ PádraigBrady Jawaban yang diperbarui. Namun, melihat banyak penolakan di utas coreutils Anda. Intinya adalah Anda menciptakan lebih banyak pekerjaan untuk orang-orang, dan Anda melakukannya atas nama OS yang merupakan tiruan dari OS dari tahun 1970. Jika orang menginginkan sesuatu yang berbeda, mereka akan memilihnya.
Jan Kyu Peblik
43
@ PádraigBrady Perubahan ini telah menyebabkan saya jengkel dan terbuang beberapa jam untuk mencari penyebab dan solusi. Saya tidak bermaksud negatif - Saya hanya berbagi sudut pandang orang lain! Memodifikasi perilaku inti memiliki implikasi yang sangat besar ..
mafrosis
52
Sebagai seseorang yang menggunakan sistem * nix selama 30 tahun, saya menemukan perubahan serampangan seperti ini cukup mengganggu. Mereka memecahkan skrip lama, untuk satu hal. Mereka juga melanggar Asas Terkecil Ketertinggalan. "Opt-in" seharusnya menjadi default di sini, seperti disebutkan di atas.
Brian Clapper
28
@ PádraigBrady Itu masih bukan cara untuk mendorong perubahan tersebut. Akan jauh lebih konstruktif untuk memiliki perilaku ikut serta daripada aktif secara default. Ini juga secara salah mengisyaratkan ini adalah bagaimana nama file disimpan, singkatnya dengan lsapa yang Anda lihat tidak lagi adalah bagaimana itu disimpan. Fitur itu harus opsional, bukan standar.
91

Anda dapat memilih gaya kutipan :

ls --quoting-style=literal

Sama seperti:

ls -N

atau:

QUOTING_STYLE=literal ls

Jadikan sebagai alias, atau atur agar export QUOTING_STYLE=literalAnda .bashrcmencapai perilaku pra-8.25.

cuonglm
sumber
11
tampaknya agak aneh saya harus melakukan itu untuk mendapatkan perilaku unix-y yang normal. Juga, saya ingin default lama. Saya tidak berpikir melarikan diri adalah default lama - saya pikir itu dicetak persis apa yang sebenarnya ada.
Wyatt8740
9
Untuk perilaku pra-8.25, gunakan export QUOTING_STYLE=literaldi bashrc Anda.
Lekensteyn
2
atau gunakan -N, tampaknya. Saya hanya mengkompilasi versi saya sendiri karena saya sudah memiliki pengaturan repositori pribadi.
Wyatt8740
2
@LSpice Saya telah mengedit posting untuk digunakan literalalih-alih escape(Saya percaya bahwa @cuonglm hanya ingin menunjukkan cara mengubah gaya, tidak secara khusus menargetkan escapegaya).
Lekensteyn
5
Jawaban ini layak mendapatkan lebih banyak suara. Ini langsung membahas apa yang ditanyakan si penanya menghindari jawaban birokratis. Memang, pendekatan variabel lingkungan tampaknya cukup elegan. (Saya pribadi lebih suka perilaku baru karena lebih menyukai tindakan C&P yang lebih efisien), namun, ls cukup pintar untuk berperilaku dengan cara lama ketika pengalihan digunakan, jadi tidak ada salahnya untuk skrip yang menggunakan output ls.
Marcelo
42

Beberapa poin tentang perubahan itu.

  • Itu diperkenalkan di coreutils v8.25, dan keselarasan ditingkatkan di v8.26
  • Ini hanya terjadi ketika keluaran ke terminal sehingga tidak merusak skrip
  • Ini merusak output untuk pengguna untuk file yang mengandung spasi
  • Ini membersihkan output sehingga aman untuk menyalin dan menempel
  • Output sekarang selalu valid untuk menyalin dan menempel kembali ke shell
  • Pengguna dapat kembali ke format lama dengan menambahkan -N ke alias ls mereka
Pádraig Brady
sumber
7
Contoh terakhir saya tidak ambigu? Mungkin tidak - tetapi ini tentu membingungkan dan membutuhkan lebih banyak waktu untuk menguraikan. Saya pikir ini adalah perubahan yang mengerikan (tidak ada pelanggaran yang ditujukan kepada Anda). Terima kasih atas tip aliasnya.
Wyatt8740
27
Catatan: perubahan ini diperkenalkan di coreutils 8.25 ( komit , ditulis oleh Pádraig yang sama dengan posting ini). Secara pribadi saya berpikir bahwa perilaku ini adalah suboptimal, ia merusak perataan setiap kali ruang terjadi dalam nama file.
Lekensteyn
10
permintaan maaf saya - tampaknya Anda setidaknya dengan aman mengutip kutipan shell. saya masih tidak menyukainya. opsinya baik-baik saja - tetapi mengubah perilaku default yang ditentukan dengan sangat baik dari utilitas inti unix yang sudah berumur beberapa dekade sedemikian rupa sehingga mengurangi kebenarannya hanya bisa menjadi ide yang buruk .
mikeserv
12
@ PádraigBrady Jadi, apakah Anda akan tetap lsrusak? Lihatlah semua argumen yang menentang perubahan Anda. Tidak ada yang menginginkannya. Mungkin sudah waktunya untuk meminta maaf kepada dunia dan membatalkannya.
Chris Warrick
6
@ PádraigBrady Jadi terlepas dari banyak orang yang telah menjelaskan bagaimana ini salah, rusak, dll, Anda masih tidak akan mengembalikan ini sehingga defaultnya tidak berubah? Bertentangan dengan kepercayaan Anda, perubahan ini membingungkan bukan disambigran. Menyarankan agar orang menetapkan variabel lingkungan atau alias asinine, paling banter.
Markus