O que usar quando o comando “ls” não funciona?

14

Eu tentei usar o comando ls e recebi um erro:

bash: /bin/ls: cannot execute binary file

O que posso usar em vez deste comando?

    
por jimmij 20.06.2015 / 07:08

7 respostas

30

Você pode usar os comandos echo ou find em vez de ls :

echo *

ou:

find -printf "%M\t%u\t%g\t%p\n"
    
por 20.06.2015 / 07:09
24

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

printf '%s\n' *

printf é superior a echo nessa situação em que echo não respeita o "traço duplo" ( -- ) para indicar o fim da lista de argumentos (em alguns sistemas, incluindo o Ubuntu 14.04, que é o que testei 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 alcançar 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 usar printf ). / p>

Note que você deve sempre usar uma string de formatação como a acima ao lidar com dados desconhecidos com printf , caso contrário você poderia receber resultados inesperados (graças 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 solução de string de formatação printf + pode manipular uma grande variedade de nomes de arquivos (e também trata arquivos "ocultos", isto é, aqueles que começam com . , o mesmo 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 o seu printf suportar %q , você também poderá usar isso ( printf '%q\n' * ). Isso irá escapar de espaços, novas linhas, etc., se houver algum caractere estranho nos seus nomes de arquivos. (Agradecimentos a @muru no bate-papo por apontar isso !)

    
por 20.06.2015 / 07:45
8

Você provavelmente deve usar os utilitários file e uname para ter uma ideia melhor do que está acontecendo com a sua máquina. Seu erro é indicativo de um executável binário compilado para uma arquitetura de sistema incompatível com aquele no qual ele é invocado.

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á uma pequena execução de alguns comandos executados no meu tablet Android em uma conexão ssh para 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
    
por 20.06.2015 / 10:04
5

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

$ thisisnotacommand ./public_html/<TAB>
acc/              papers/           android/          l/
sdr/              blast             formalcss.html    switch/
busy/             formalcss.tar.gz  others/           together.jpg
    
por 20.06.2015 / 09:45
3

Se você quiser algo mais como ls -l (tamanho do arquivo, permissões, proprietário, timestamps etc.), então stat -- * pode 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: -
$ 

Como alternativa, tudo que você queria fazer é soltar ls e, em seguida, tentar sl . ;-) (vá em frente - experimente ... você pode ter que instalá-lo)

    
por 21.06.2015 / 06:52
3

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

dir

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

O benefício de usar dir (em vez de, por exemplo, sistema de completação de shell) é a disponibilidade de diferentes opções como ordenação, exibição de arquivos ocultos, coloração, etc., como no programa ls padrão.

BTW, eu acho que seu nome vem do sistema Windows (ou melhor dos).

    
por 20.06.2015 / 18:33
1

use

 echo -- *
    find . -printf "%M\t%u\t%g\t%p\n"
    ls -C -b
    
por 21.06.2015 / 02:45