Cosa usare quando il comando "ls" non funziona?


15

Ho provato a usare il lscomando e ho ricevuto un errore:

bash: /bin/ls: cannot execute binary file

Cosa posso usare al posto di questo comando?


Forse hai libc*sold-linux*so
rovinato il

31
Personalmente, mi concentrerei sulla riparazione del mio sistema, a meno che questo non sia un esperimento stravagante di pensiero.
Faheem Mitha,

2
@BasileStarynkevitch non ne ha mai sentito parlare, ma Busybox è comunemente disponibile e può intervenire.
Muru,

8
... un cd di ripristino del sistema?
Federico Poloni,

1
Una domanda che affronta il problema reale in questi casi è superuser.com/questions/435988 . E lungi dall'essere insolito, come implicito, sashè disponibile su Ubuntu Linux , come shell / sash nell'albero delle porte di FreeBSD, come pacchetto Gentoo , così come in altri luoghi incluso direttamente dal suo autore .
JdeBP,

Risposte:


32

È possibile utilizzare i comandi echoo findanziché ls:

echo *

o:

find -printf "%M\t%u\t%g\t%p\n"

7
Vorrei usareecho -- *
Edward Torvalds il

9
@Invoker: se ti capita di avere un file chiamato -nnella directory corrente, verrebbe interpretato come un flag, non qualcosa da echeggiare.
MvG,

2
Sarebbetouch ./-n
Basile Starynkevitch il

1
@Invoker L'ordine alfabetico è importante. Esegui quell'allineatore per un caso in cui ciò fa la differenza:rm -rf /tmp/foo && mkdir /tmp/foo && cd /tmp/foo && touch ./-n oops && set -x && ls && echo *
jlliagre

3
echoNon sembra onore --, di per sé . Allora, come è echo -- *meglio echo "" *o meglio ancora echo "The file(s) are:" *?
G-Man dice 'Reinstate Monica' il

24

Puoi anche usare il printfcomando, invece di echo:

printf '%s\n' *

printfè superiore a echoin questa situazione in quanto echofa non rispettare il "doppio trattino" ( --) per indicare la fine della lista degli argomenti (su alcuni sistemi, tra cui Ubuntu 14.04 che è quello che ho testato su):

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

In questo caso, non è possibile ottenere il risultato desiderato con echo (poiché un file chiamato -nviene interpretato come un'opzione e il doppio trattino non funziona, quindi è necessario utilizzare printf).

Nota che dovresti sempre usare una stringa di formato come sopra quando fare con dati sconosciuti printf, poiché altrimenti potresti ricevere risultati inaspettati (grazie a @ G-Man per averlo sottolineato nei commenti!):

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

Un file chiamato \n viene interpretato come una nuova riga da printf. Per evitare ciò, usiamo una stringa di formattazione per printf( %s) e le passiamo i nomi dei file (espansi via globbing, come prima).

Questa printfsoluzione + stringa di formattazione può gestire un'ampia varietà di nomi di file (e tratta anche file "nascosti", ovvero quelli che iniziano con un ., lo stesso dils ):

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

Se il tuo printfsupporto %q, puoi anche usare quello ( printf '%q\n' *). Questo sfuggirà a spazi, newline, ecc. Se ci sono caratteri strani nei nomi dei file. (Grazie a @muru in chat per averlo segnalato !)


2
Quando hai a che fare con dati sconosciuti, dovresti SEMPRE utilizzare '%s'(con \ne / o qualsiasi altro testo costante che desideri). Ad esempio, prova i comandi touch '%.0s' foo bar; ls; printf -- *. Al contrario, non vedo perché hai bisogno --di una '%s\n'stringa di formato.
G-Man dice 'Reinstate Monica' il

@ G-Man buon punto! Grazie, ho trascurato l'inutile --con la stringa di formato e ho modificato il mio post per affrontare l'altra cosa.
Doorknob,

Il -nnome del file onestamente non dovrebbe essere affatto un problema per POSIX-2001 + echo- sui sistemi SUSv3 echoè necessaria l' utilità per non accettare alcuna opzione. bash's echoed alcuni altri fanno gestire l'opzione, però, ma bashpossono essere compilati con l'opzione di compilazione --enable-xpg-echo-defaultper rendere comportarsi correttamente tutto il tempo. Un comportamento corretto per echo, tuttavia, significa interpretare sempre le fughe di gioco nei suoi argomenti. Quindi qualsiasi nome di file con una escape in stile C non verrebbe scritto nell'output con fedeltà - echolo tradurrebbe.
Mikeserv,

2
per favore, per favore, tutti dovrebbero smettere di raccomandare '-' quando la faq di unix da più di 10 anni spiega che usare "./" è meglio e più portatile (funziona con tutti i programmi anche quelli (molti) che non gestiscono "- ')
Olivier Dulac,

1
@OliverDulac - nemmeno quello sarebbe hel [w / a conforme echo.
Mikeserv,

8

Probabilmente dovresti usare i programmi di utilità filee unameper avere un'idea migliore di cosa diavolo sta succedendo con la tua macchina. Il tuo errore è indicativo di un eseguibile binario compilato per un'architettura di sistema incompatibile con quello su cui viene invocato.

Sulla mia macchina:

uname -m; file /bin/ls

... stampe ...

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

... perché tutto va bene con il mondo lì. Tuttavia, ecco una piccola serie di alcuni comandi eseguiti dal mio tablet Android su una sshconnessione al mio desktop ...

#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

Questa è un'ottima risposta che copre uno scenario e affronta la potenziale causa sottostante.
Pranab,

frainteso ^^ scusa. perché non semplicemente copiare e usare il file? perché tutta la faccenda di Homedir? scp sul desktop, file su di esso e bash ./it?
Olivier Dulac,

@OlivierDulac -hmm .. non sono sicuro di aver capito cosa stai chiedendo esattamente. Il fatto HOME=è che posso solo fare ~un sacco di volte invece di ./arm_ls - per comodità. Il punto centrale dell'esercizio è che non posso usare il binario arm sul mio desktop x86, e volevo che l'output di filemostrasse che è un tipo di binario molto diverso da quello nativo del sistema - che è mostrato in alto. E così piuttosto che shpw un'intera cross-compilazione, ho scelto di compilare un binario incompatibile che avevo a disposizione sul mio braccio dev al mio dispositivo x86 e mostrare i risultati e come gestire l' basherrore.
Mikeserv,

1
oh, era solo per salvare qualche battitura? ok, ma penso che lo renda più confuso di quanto dovrebbe essere (non è codegolf ^^)
Olivier Dulac,

1
@OliverDulac - ovviamente non è un codice oro, ma è conveniente, non è affatto ambiguo e odio scrivere il pollice.
Mikeserv,

5

Usando bash (o molte altre shell), è possibile utilizzare il completamento della scheda per elencare i file:

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

3

Se vuoi qualcosa di più simile ls -l(dimensioni del file, autorizzazioni, proprietario, timestamp, ecc.), Allora stat -- *potrebbe essere utile:

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

In alternativa, se tutto ciò che volevi fare è sbagliare ls, prova slinvece . ;-) (continua - provalo ... potresti doverlo installare)


3

Esiste un'utilità molto simile disponibile su molti sistemi:

dir

Secondo le pagine informative è equivalente ls -C -b, ma è un file binario autonomo.

Il vantaggio dell'utilizzo dir(anziché ad esempio del sistema di completamento della shell) è la disponibilità di diverse opzioni come l'ordinamento, la visualizzazione di file nascosti, la colorazione ecc., Proprio come nel lsprogramma standard .

A proposito, immagino che il suo nome derivi dal sistema di Windows (o meglio).


1

uso

 echo -- *
    find . -printf "%M\t%u\t%g\t%p\n"
    ls -C -b
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.