Apa yang harus digunakan ketika perintah "ls" tidak berfungsi?

15

Saya mencoba menggunakan lsperintah dan mendapat kesalahan:

bash: /bin/ls: cannot execute binary file

Apa yang bisa saya gunakan daripada perintah ini?

jimmij
sumber
Mungkin Anda mengacaukan Anda libc*soatau Andald-linux*so
Basile Starynkevitch
31
Secara pribadi, saya akan fokus pada memperbaiki sistem saya, kecuali jika ini adalah eksperimen pemikiran yang aneh.
Faheem Mitha
2
@BasileStarynkevitch tidak pernah mendengarnya, tetapi Busybox umumnya tersedia dan dapat masuk.
muru
8
... sebuah cd penyelamatan sistem?
Federico Poloni
1
Pertanyaan yang membahas masalah aktual dalam kasus tersebut adalah superuser.com/questions/435988 . Dan jauh dari tidak umum, seperti tersirat, sashtersedia di Ubuntu Linux , sebagai shells / sash di pohon port FreeBSD, sebagai paket Gentoo , serta tempat-tempat lain termasuk langsung dari penulisnya .
JdeBP

Jawaban:

32

Anda dapat menggunakan perintah echoatau findbukannya ls:

echo *

atau:

find -printf "%M\t%u\t%g\t%p\n"
Invoker
sumber
7
Saya akan menggunakanecho -- *
Edward Torvalds
9
@Invoker: Jika Anda memiliki file yang dipanggil -ndi direktori saat ini, itu akan ditafsirkan sebagai flag, bukan sesuatu untuk diulang.
MvG
2
Itu akan menjaditouch ./-n
Basile Starynkevitch
1
@Invoker Urutan abjad penting. Jalankan oneliner itu untuk kasus di mana itu membuat perbedaan:rm -rf /tmp/foo && mkdir /tmp/foo && cd /tmp/foo && touch ./-n oops && set -x && ls && echo *
jlliagre
3
echotampaknya tidak menghormati --, per se . Jadi bagaimana yang echo -- *lebih baik dari echo "" *atau, lebih baik echo "The file(s) are:" *,?
G-Man Mengatakan 'Reinstate Monica'
24

Anda juga dapat menggunakan printfperintah, alih-alih gema:

printf '%s\n' *

printflebih unggul echodalam situasi ini bahwa echotidak tidak menghormati "dash ganda" ( --) untuk menandakan akhir dari daftar argumen (pada beberapa sistem, termasuk Ubuntu 14.04 yang merupakan apa yang saya diuji pada):

llama@llama:~$ mkdir -p Misc/unix210948
llama@llama:~$ cd !$
cd Misc/unix210948
llama@llama:~/Misc/unix210948$ touch -- -n
llama@llama:~/Misc/unix210948$ ls
-n
llama@llama:~/Misc/unix210948$ echo *
llama@llama:~/Misc/unix210948$ echo -- *
-- -n
llama@llama:~/Misc/unix210948$ printf '%s\n' *
-n

Dalam hal ini, Anda tidak dapat mencapai hasil yang diinginkan echo(karena file yang dipanggil -nditafsirkan sebagai opsi, dan dasbor ganda tidak berfungsi, jadi Anda harus menggunakan printf).

Perhatikan bahwa Anda harus selalu menggunakan string format seperti di atas ketika berhadapan dengan data yang tidak dikenal printf, karena jika tidak, Anda dapat menerima hasil yang tidak terduga (terima kasih kepada @ G-Man karena menunjukkan ini di komentar!):

llama@llama:~/Misc/unix210948$ rm ./-n
llama@llama:~/Misc/unix210948$ touch '\n'
llama@llama:~/Misc/unix210948$ ls
\n
llama@llama:~/Misc/unix210948$ printf -- *

llama@llama:~/Misc/unix210948$ printf '%s\n' *
\n

File yang dipanggil \nditafsirkan sebagai baris baru oleh printf. Untuk menghindari ini, kami menggunakan string pemformatan untuk printf(%s ) dan memberikannya nama-nama file (diperluas melalui globbing, seperti sebelumnya).

printfSolusi string pemformatan + ini dapat menangani berbagai nama file (dan juga memperlakukan file "tersembunyi", yaitu, yang dimulai dengan a ., sama dengan ls):

llama@llama:~/Misc/unix210948$ rm ./*
zsh: sure you want to delete all the files in /home/llama/Misc/unix210948/. [yn]? y
llama@llama:~/Misc/unix210948$ touch -- '-n' '\n' 'name with spaces' '.hidden'
llama@llama:~/Misc/unix210948$ ls
-n  \n  name with spaces
llama@llama:~/Misc/unix210948$ printf '%s\n' *
-n
\n
name with spaces

Jika printfdukungan %qAnda, Anda juga dapat menggunakannya ( printf '%q\n' *). Ini akan keluar dari spasi, baris baru, dll. Jika ada karakter aneh di nama file Anda. (Terima kasih kepada @muru dalam obrolan karena menunjukkan ini !)

Gagang pintu
sumber
2
Saat berurusan dengan data yang tidak dikenal, Anda harus SELALU menggunakan '%s'(dengan \ndan / atau teks konstan lainnya yang Anda inginkan). Misalnya, coba perintahnya touch '%.0s' foo bar; ls; printf -- *. Sebaliknya, saya tidak melihat mengapa Anda perlu --ketika Anda memiliki '%s\n'string format.
G-Man Mengatakan 'Reinstate Monica'
@ G-Man Poin bagus! Terima kasih, saya mengabaikan yang tidak perlu --dengan format string, dan saya telah mengedit posting saya untuk mengatasi hal lainnya.
Gagang pintu
Nama -nfile secara jujur seharusnya tidak menjadi masalah sama sekali untuk POSIX-2001 + echo- pada sistem SUSv3 echoutilitas diperlukan untuk tidak menerima opsi apa pun. bash's echodan beberapa orang lain melakukan menangani pilihan sekalipun, tetapi bashdapat dikompilasi dengan opsi membangun --enable-xpg-echo-defaultuntuk membuatnya berperilaku dengan benar sepanjang waktu. Perilaku yang benar untuk echo, bagaimanapun, berarti selalu menafsirkan serangan balasan lolos dalam argumennya. Jadi setiap nama file dengan pelolosan gaya-C tidak akan ditulis ke output dengan kesetiaan - echoakan menerjemahkannya.
mikeserv
2
tolong, tolong, semua orang harus berhenti memberi rekomendasi ulang '-' ketika unix faq sejak lebih dari 10 tahun menjelaskan bahwa menggunakan "./" lebih baik dan lebih portabel (bekerja dengan semua program bahkan (banyak) yang tidak menangani '- ')
Olivier Dulac
1
@OliverDulac - bahkan itu tidak akan membantu echo.
mikeserv
8

Anda mungkin harus menggunakan filedan unameutilitas untuk mendapatkan gambaran yang lebih baik tentang apa yang sedang terjadi dengan mesin Anda. Kesalahan Anda adalah indikasi biner yang dapat dieksekusi dikompilasi untuk arsitektur sistem yang tidak kompatibel dengan yang di dalamnya ia dipanggil.

Di mesin saya:

uname -m; file /bin/ls

... mencetak ...

x86_64
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=..., stripped

... karena semuanya benar dengan dunia di sana. Namun, inilah beberapa perintah dijalankan dari tablet android saya pada sshkoneksi ke desktop saya ...

#first copy android ls to desktop
scp /system/bin/ls "$ssh:arm_ls"

ls               100%  151KB 151.4KB/s   00:00

#next login to desktop and run the following
ssh "$ssh" '
   HOME=./arm_ls
   chmod +x ~
   file ~
   bash -c ~ ||
   rm ~
'

./arm_ls: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped
bash: ./arm_ls: cannot execute binary file: Exec format error
mikeserv
sumber
Ini adalah jawaban yang bagus yang mencakup satu skenario dan membahas potensi penyebab yang mendasarinya.
Pranab
salah membaca ^^ maaf. mengapa tidak menyalin dan menggunakan file saja? mengapa semuanya homedir? scp ke desktop, file di atasnya, dan bash ./it?
Olivier Dulac
@OlivierDulac -hmm .. saya tidak yakin saya mendapatkan inti dari apa yang Anda minta sebenarnya. The HOME=hal yang jadi saya hanya dapat melakukan ~beberapa kali bukan ./arm_ls - untuk kenyamanan. Inti dari latihan ini adalah saya tidak dapat menggunakan arm binary pada desktop x86 saya, dan saya ingin output fileuntuk menunjukkan bahwa itu adalah jenis biner yang sangat berbeda dari binary asli sydtem - yang ditampilkan di atas. Dan daripada shpw seluruh cross-compile, saya memilih untuk cpy biner yang tidak kompatibel yang saya miliki untuk saya di dev lengan saya ke perangkat x86 saya dan menunjukkan hasil dan cara menghapus bashkesalahan.
mikeserv
1
oh, itu hanya menghemat beberapa pengetikan? ok, tapi saya pikir itu membuatnya lebih membingungkan dari yang seharusnya (itu bukan codegolf ^^)
Olivier Dulac
1
@ OliverDulac - tentu saja bukan kode emas, tapi lebih mudah, sama sekali tidak ambigu, dan saya benci mengetik jempol.
mikeserv
5

Dengan menggunakan bash (atau banyak shell lain), Anda dapat menggunakan penyelesaian tab untuk membuat daftar file:

$ thisisnotacommand ./public_html/<TAB>
acc/              papers/           android/          l/
sdr/              blast             formalcss.html    switch/
busy/             formalcss.tar.gz  others/           together.jpg
pengguna1998586
sumber
3

Jika Anda menginginkan sesuatu yang lebih seperti ls -l(ukuran file, izin, pemilik, cap waktu, dll), maka stat -- *mungkin bermanfaat:

$ ls -l
total 8
-rw-rw-r-- 1 ubuntu ubuntu   4 Jun 20 21:50 a.txt
-rw-rw-r-- 1 ubuntu ubuntu 279 Jun 20 21:50 b.txt
$ stat -- *
  File: ‘a.txt’
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 787691      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/  ubuntu)   Gid: ( 1000/  ubuntu)
Access: 2015-06-20 21:50:23.395223851 -0700
Modify: 2015-06-20 21:50:23.395223851 -0700
Change: 2015-06-20 21:50:23.395223851 -0700
 Birth: -
  File: ‘b.txt’
  Size: 279         Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 844130      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/  ubuntu)   Gid: ( 1000/  ubuntu)
Access: 2015-06-20 21:50:31.763084155 -0700
Modify: 2015-06-20 21:50:51.066758216 -0700
Change: 2015-06-20 21:50:51.066758216 -0700
 Birth: -
$ 

Atau jika semua yang Anda ingin lakukan adalah misspell ls, maka cobalah slsebaliknya . ;-) (terus - coba ... Anda mungkin harus menginstalnya)

Trauma Digital
sumber
3

Ada utilitas yang sangat mirip tersedia di banyak sistem:

dir

Menurut halaman info itu setara dengan ls -C -b, tetapi itu adalah file biner mandiri.

Manfaat menggunakan dir(daripada misalnya sistem penyelesaian shell) adalah tersedianya berbagai opsi seperti penyortiran, menampilkan file tersembunyi, pewarnaan dll., Seperti dalam lsprogram standar .

BTW, saya kira namanya berasal dari sistem windows (atau lebih tepatnya dos).

jimmij
sumber
1

menggunakan

 echo -- *
    find . -printf "%M\t%u\t%g\t%p\n"
    ls -C -b

sumber