O que usar quando o comando "ls" não funciona?

15

Eu tentei usar o lscomando e recebi um erro:

bash: /bin/ls: cannot execute binary file

O que posso usar em vez deste comando?

jimmij
fonte
Talvez você tenha estragado tudo o que você libc*soou seuld-linux*so
Basile Starynkevitch
31
Pessoalmente, eu me concentraria em consertar meu sistema, a menos que seja um experimento maluco.
Faheem Mitha
2
@BasileStarynkevitch nunca ouvi falar disso, mas Busybox é comumente disponível e pode intervir.
Muru
8
... um CD de resgate do sistema?
Federico Poloni
1
Uma pergunta que aborda o problema real nesses casos é superuser.com/questions/435988 . E longe de ser incomum, como está implícito, sashestá disponível no Ubuntu Linux , como shells / sash na árvore de portas do FreeBSD, como um pacote Gentoo , além de outros locais, inclusive diretamente de seu autor .
JdeBP

Respostas:

32

Você pode usar os comandos echoou em findvez de ls:

echo *

ou:

find -printf "%M\t%u\t%g\t%p\n"
Invoker
fonte
7
Eu usariaecho -- *
Edward Torvalds
9
@ Invoker: Se você tiver um arquivo chamado -nno diretório atual, isso seria interpretado como uma bandeira, não como algo para ecoar.
MvG
2
Seriatouch ./-n
Basile Starynkevitch
1
A ordem alfabética da @Invoker é importante. Execute que oneliner para um caso em que faz a diferença:rm -rf /tmp/foo && mkdir /tmp/foo && cd /tmp/foo && touch ./-n oops && set -x && ls && echo *
jlliagre
3
echoparece não honrar --, por si só . Então, como é echo -- *melhor echo "" *ou melhor ainda echo "The file(s) are:" *?
G-Man diz 'Reinstate Monica'
24

Você também pode usar o printfcomando, em vez de echo:

printf '%s\n' *

printfé superior a echonesta situação em que echose não respeitar o "traço duplo" ( --) para significar o fim da lista de argumentos (em alguns sistemas, incluindo Ubuntu 14.04 que é o que eu testei-o em):

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

Nesse caso, você não pode obter o resultado desejado com echo(já que um arquivo chamado -né interpretado como uma opção e o traço duplo não funciona, portanto, você deve usá-lo printf).

Observe que você sempre deve usar uma string de formato como a acima ao lidar com dados desconhecidos printf, pois caso contrário, poderá receber resultados inesperados (obrigado ao @ G-Man por apontar isso nos comentários!):

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

Um arquivo chamado \né interpretado como uma nova linha por printf. Para evitar isso, usamos uma string de formatação para printf( %s) e passamos os nomes dos arquivos (expandidos via globbing, como antes).

Essa printfsolução de sequência de formatação + pode lidar com uma grande variedade de nomes de arquivos (e também trata arquivos "ocultos", ou seja, aqueles que começam com a ., da mesma forma que 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

Se você printfsuporta %q, você também pode usar isso ( printf '%q\n' *). Isso escapará a espaços, novas linhas etc. se houver caracteres estranhos em seus nomes de arquivos. (Obrigado a @muru no chat por apontar isso !)

Maçaneta
fonte
2
Ao lidar com dados desconhecidos, você SEMPRE deve usar '%s'(com \ne / ou qualquer outro texto constante que desejar). Por exemplo, tente os comandos touch '%.0s' foo bar; ls; printf -- *. Por outro lado, não vejo por que você precisa --quando possui uma '%s\n'string de formato.
G-Man diz 'Reinstate Monica'
@ G-Man Bom ponto! Obrigado, eu ignorei o desnecessário --com a string de formato e editei minha postagem para resolver a outra coisa.
Maçaneta 20/15
O -nnome do arquivo honestamente não deve ser um problema para um POSIX-2001 + echo- nos sistemas SUSv3, o echoutilitário é obrigado a não aceitar nenhuma opção. bash's echoe alguns outros fazem lidar com a opção embora, mas bashpode ser compilado com a opção de construção --enable-xpg-echo-defaultpara torná-lo comportar corretamente o tempo todo. O comportamento corretoecho , no entanto, significa sempre interpretar escapes de folga em seus argumentos. Portanto, qualquer nome de arquivo com uma fuga no estilo C não seria gravado na saída com fidelidade - echoo traduziria.
mikeserv
2
por favor, por favor, todos devem parar de recomendar '-' quando o faq do unix, há mais de 10 anos, explica que o uso de "./" é melhor e mais portátil (funciona com todos os programas, mesmo os (muitos) que não lidam com '- ')
Olivier Dulac
1
@ OliverDulac - nem isso ajudaria [com um conforme echo.
mikeserv
8

Você provavelmente deve usar os utilitários filee unamepara ter uma idéia melhor do que diabos está acontecendo com sua máquina. Seu erro é indicativo de um executável binário compilado para uma arquitetura de sistema incompatível com a qual é invocada.

Na minha máquina:

uname -m; file /bin/ls

... imprime ...

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

... porque está tudo bem com o mundo lá. No entanto, aqui estão alguns comandos executados no meu tablet Android em uma sshconexão com a minha área de trabalho ...

#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
fonte
Essa é uma ótima resposta que abrange um cenário e aborda a causa subjacente em potencial.
Pranab
lido mal ^^ desculpe. por que não apenas copiar e usar o arquivo? por que a coisa toda de homedir? scp para desktop, arquivo nele e bash ./it?
Olivier Dulac
@ OlivierDulac -hmm .. eu não tenho certeza se entendi o que você está perguntando exatamente. O HOME=problema é que eu posso fazer ~várias vezes em vez de ./arm_ls - por conveniência. O ponto principal do exercício é que eu não posso usar o binário do braço no meu desktop x86 e queria que a saída filemostrasse que é um tipo de binário muito diferente do binário do que o nativo do sydtem - que é mostrado na parte superior. E assim, em vez de enviar uma compilação cruzada inteira, optei por copiar um binário incompatível que eu tinha disponível para mim no meu braço dev para o meu dispositivo x86 e mostrar os resultados e como gerar o basherro.
mikeserv
1
ah, foi só para economizar algumas digitações? ok, mas eu acho que torna mais confuso do que deveria ser (não é codegolf ^^)
Olivier Dulac
1
@ OliverDulac - é claro que não é um código de ouro, mas é conveniente, não é nada ambíguo e eu odeio digitar polegares.
precisa saber é o seguinte
5

Usando o bash (ou muitos outros shells), você pode usar o preenchimento de guias para listar arquivos:

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

Se você quiser algo mais parecido com ls -l(tamanho do arquivo, permissões, proprietário, registros de data e hora, etc.), stat -- *poderá ser útil:

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

Alternativamente, se tudo o que você queria fazer é cometer erros de ortografia ls, em seguida, tentar slem vez . ;-) (vá em frente - experimente ... talvez seja necessário instalá-lo)

Trauma Digital
fonte
3

Existe um utilitário muito semelhante disponível em muitos sistemas:

dir

De acordo com as páginas de informações, é equivalente ls -C -b, mas é um arquivo binário independente.

O benefício de usar dir(em vez de, por exemplo, o sistema de conclusão de shell) é a disponibilidade de diferentes opções, como classificação, exibição de arquivos ocultos, cores etc., assim como no lsprograma padrão .

BTW, acho que o nome vem do sistema Windows (ou melhor, DOS).

jimmij
fonte
1

usar

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

fonte