Czego używać, gdy polecenie „ls” nie działa?

15

Próbowałem użyć lspolecenia i wystąpił błąd:

bash: /bin/ls: cannot execute binary file

Czego mogę użyć zamiast tego polecenia?

jimmij
źródło
Być może spieprzyłeś swój libc*solub swójld-linux*so
Basile Starynkevitch
31
Osobiście skupiłbym się na naprawie mojego systemu, chyba że jest to jakiś zwariowany eksperyment myślowy.
Faheem Mitha,
2
@BasileStarynkevitch nigdy o tym nie słyszałem, ale Busybox jest powszechnie dostępny i może wkroczyć.
muru
8
... płyta ratunkowa systemu?
Federico Poloni,
1
Pytanie dotyczące rzeczywistego problemu w takich przypadkach to superuser.com/questions/435988 . I wcale nie jest rzadkie, jak sugeruje, sashjest dostępne w systemie Ubuntu Linux , jako powłoki / sash w drzewie portów FreeBSD, jako pakiet Gentoo , a także w innych miejscach, w tym bezpośrednio od jego autora .
JdeBP,

Odpowiedzi:

32

Możesz użyć poleceń echolub findzamiast ls:

echo *

lub:

find -printf "%M\t%u\t%g\t%p\n"
Invoker
źródło
7
Użyłbymecho -- *
Edward Torvalds
9
@Invoker: Jeśli -nw bieżącym katalogu znajduje się plik wywoływany , zostanie on zinterpretowany jako flaga, a nie coś do echa.
MvG,
2
Byłobytouch ./-n
Basile Starynkevitch
1
@Invoker Kolejność alfabetyczna ma znaczenie. Uruchom ten oneliner w przypadku, gdy robi to różnicę:rm -rf /tmp/foo && mkdir /tmp/foo && cd /tmp/foo && touch ./-n oops && set -x && ls && echo *
jlliagre
3
echoNie wydaje się cześć --, per se . Jak więc może być echo -- *coś lepszego echo "" *lub jeszcze lepszego echo "The file(s) are:" *?
G-Man mówi „Reinstate Monica”
24

Możesz także użyć printfpolecenia zamiast echa:

printf '%s\n' *

printfjest lepszy echow tej sytuacji, że echonie nie przestrzega zasady „podwójną kreskę” ( --) oznaczać końca listy argument (w niektórych systemach, w tym Ubuntu 14.04, który jest co testowałem go):

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

W takim przypadku nie można osiągnąć pożądanego rezultatu za pomocą echo(ponieważ plik o nazwie -nzostaje zinterpretowany jako opcja, a podwójne myślenie nie działa, więc musisz użyć printf).

Pamiętaj, że zawsze powinieneś używać ciągu formatu takiego jak powyższy, gdy printfmasz do czynienia z nieznanymi danymi , ponieważ w przeciwnym razie możesz otrzymać nieoczekiwane wyniki (dzięki @ G-Man za wskazanie tego w komentarzach!):

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

Wywołany plik \njest interpretowany jako nowy wiersz przez printf. Aby tego uniknąć, używamy ciągu formatującego dla printf( %s) i przekazujemy mu nazwy plików (rozwinięte przez globbing, jak poprzednio).

To printf+ ciąg formatujący może obsługiwać wiele różnych nazw plików (a także traktuje pliki „ukryte”, to znaczy te zaczynające się od ., takie same jak 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

Jeśli twoje printfwsparcie %q, możesz również użyć tego ( printf '%q\n' *). Spowoduje to uniknięcie spacji, znaków nowej linii itp., Jeśli w nazwach plików znajdują się dziwne znaki. (Dzięki @muru na czacie za zwrócenie na to uwagi !)

Klamka
źródło
2
W przypadku nieznanych danych ZAWSZE należy używać '%s'(z \ndowolnym innym stałym tekstem). Na przykład wypróbuj polecenia touch '%.0s' foo bar; ls; printf -- *. I odwrotnie, nie rozumiem, dlaczego potrzebujesz, --gdy masz '%s\n'ciąg formatu.
G-Man mówi „Reinstate Monica”
@ G-Man Dobra uwaga! Dzięki, przeoczyłem niepotrzebne --ciągi formatujące i zredagowałem swój post, aby zająć się drugą rzeczą.
Klamka
Nazwa -npliku szczerze mówiąc nie powinna stanowić problemu dla POSIX-2001 + echo- w systemach SUSv3 echonarzędzie musi nie akceptować żadnych opcji. bash„s echo, a niektóre robią inni obsługiwać opcję chociaż, ale bashmoże zostać skompilowany z opcją build --enable-xpg-echo-defaultby zachowywał się poprawnie przez cały czas. Prawidłowe zachowanie echooznacza jednak zawsze interpretację ucieczki w argumentach. Tak więc każda nazwa pliku ze znakiem ucieczki w stylu C nie byłaby zapisywana do wyjścia z wiernością - echotłumaczyłaby to.
mikeserv
2
prosze, prosze, kazdy powinien przestac polecac '-' kiedy faq unixa od ponad 10 lat wyjasnia, ze uzywanie "./" jest lepsze i bardziej przenosne (dziala ze wszystkimi programami nawet (wieloma), które nie obslugujac "- ')
Olivier Dulac
1
@OliverDulac - nawet to by nie pomogło [w / a zgodności echo.
mikeserv
8

Prawdopodobnie powinieneś użyć narzędzi filei, unameaby uzyskać lepszy pogląd na to, co u diabła dzieje się na twoim komputerze. Twój błąd wskazuje na binarny plik wykonywalny skompilowany dla architektury systemu niezgodnej z architekturą, na której jest wywoływany.

Na mojej maszynie:

uname -m; file /bin/ls

... drukuje ...

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

... ponieważ wszystko jest w porządku z tamtym światem. Oto jednak kilka poleceń uruchamianych z mojego tabletu z Androidem po sshpołączeniu z komputerem ...

#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
źródło
To świetna odpowiedź, która obejmuje jeden scenariusz i dotyczy potencjalnej przyczyny.
Pranab,
źle odczytane ^^ przepraszam. dlaczego nie skopiować i użyć pliku? dlaczego cała ta sprawa z Homedir? scp na pulpit, plik na nim i bash ./it?
Olivier Dulac
@OlivierDulac -hmm .. nie jestem pewien, czy dostaję sedno tego, o co dokładnie pytasz. Chodzi HOME=o to, że mogę zrobić ~kilka razy zamiast ./arm_ls - dla wygody. Cały sens ćwiczenia polega na tym, że nie mogę użyć pliku binarnego arm na moim pulpicie x86 i chciałem, aby wynik filepokazał, że jest to bardzo odmienny rodzaj pliku binarnego niż natywny plik sydtem - co pokazano na górze. Więc zamiast shpw całej kompilacji krzyżowej, wybrałem cpy do niekompatybilnego pliku binarnego, który miałem do dyspozycji na moim ramieniu dev dla mojego urządzenia x86 i pokazałem wyniki i jak naprawić bashbłąd.
mikeserv
1
och, to było po prostu zaoszczędzić trochę pisania? ok, ale myślę, że to sprawia, że ​​jest to bardziej mylące niż powinno być (nie jest to codegolf ^^)
Olivier Dulac
1
@OliverDulac - oczywiście nie jest to złoty kod, ale jest wygodny, wcale nie jest dwuznaczny i nie znoszę pisania kciukiem.
mikeserv
5

Używając bash (lub wielu innych powłok), możesz użyć uzupełniania tabulatorów, aby wyświetlić listę plików:

$ thisisnotacommand ./public_html/<TAB>
acc/              papers/           android/          l/
sdr/              blast             formalcss.html    switch/
busy/             formalcss.tar.gz  others/           together.jpg
użytkownik1998586
źródło
3

Jeśli chcesz czegoś bardziej podobnego ls -l(rozmiar pliku, uprawnienia, właściciel, znaczniki czasu itp.), stat -- *Może być pomocne:

$ 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: -
$ 

Alternatywnie, jeśli wszystko, co chciałeś zrobić, to źle napisać ls, spróbuj slzamiast tego . ;-) (kontynuuj - spróbuj ... może być konieczne zainstalowanie)

Cyfrowa trauma
źródło
3

Istnieje bardzo podobne narzędzie dostępne w wielu systemach:

dir

Według stron informacyjnych jest to równoważne ls -C -b, ale jest to samodzielny plik binarny.

Zaletą używania dir(zamiast na przykład systemu uzupełniania powłoki) jest dostępność różnych opcji, takich jak sortowanie, wyświetlanie ukrytych plików, kolorowanie itp., Tak jak w standardowym lsprogramie.

BTW, chyba nazwa pochodzi od systemu Windows (a raczej dos).

jimmij
źródło
1

posługiwać się

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

źródło