Что использовать, если команда «ls» не работает?

15

Я попытался использовать lsкоманду и получил ошибку:

bash: /bin/ls: cannot execute binary file

Что я могу использовать вместо этой команды?

jimmij
источник
Возможно, ты напортачил с твоим libc*soили с твоимld-linux*so
Василий Старынкевич
31
Лично я бы сосредоточился на исправлении своей системы, если это не какой-то дурацкий мысленный эксперимент.
Фахим Митха
2
@BasileStarynkevitch никогда не слышал об этом, но Busybox общедоступен и может вмешаться.
Муру
8
... система спасения компакт-диска?
Федерико Полони
1
Вопрос, решающий актуальную проблему в таких случаях, это superuser.com/questions/435988 . И далеко не редкость, как подразумевается, sashдоступна в Ubuntu Linux , как shell / sash в дереве портов FreeBSD, как пакет Gentoo , а также в других местах, в том числе непосредственно от его автора .
JdeBP

Ответы:

32

Вы можете использовать команды echoили findвместо ls:

echo *

или:

find -printf "%M\t%u\t%g\t%p\n"
Чешуи
источник
7
Я бы использовалecho -- *
Эдвард Торвальдс
9
@Invoker: Если у вас есть файл, вызываемый -nв текущем каталоге, он будет интерпретирован как флаг, а не как нечто, что должно быть отражено.
MvG
2
Это было быtouch ./-n
Василий Старынкевич
1
@ Invoker Алфавитный порядок имеет значение. Запустите этот oneliner для случая, когда это имеет значение:rm -rf /tmp/foo && mkdir /tmp/foo && cd /tmp/foo && touch ./-n oops && set -x && ls && echo *
jlliagre
3
echoпохоже, не в чести --, как таковой . Так как же echo -- *лучше echo "" *или еще лучше echo "The file(s) are:" *?
G-Man говорит: «Восстановите Монику»
24

Вы также можете использовать printfкоманду вместо echo:

printf '%s\n' *

printfпревосходит echoв этой ситуации то, echoчто не использует «двойную черту» ( --) для обозначения конца списка аргументов (в некоторых системах, включая Ubuntu 14.04, на котором я тестировал):

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

В этом случае вы не можете достичь желаемого результата с echo(так как вызываемый файл -nинтерпретируется как опция, а двойная черта не работает, поэтому вы должны использовать printf).

Обратите внимание, что вы всегда должны использовать строку формата, подобную приведенной выше, при работе с неизвестными данными printf, поскольку в противном случае вы можете получить неожиданные результаты (спасибо @ G-Man за то, что указал на это в комментариях!):

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

Вызываемый файл \nинтерпретируется как перевод строки printf. Чтобы избежать этого, мы используем форматирующую строку для printf( %s) и передаем ей имена файлов (которые расширяются с помощью глобализации, как и раньше).

Это printfрешение + форматирование строки может обрабатывать самые разные имена файлов (а также обрабатывать «скрытые» файлы, то есть те, которые начинаются с ., так же, как 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

Если вы printfподдерживаете %q, вы также можете использовать это ( printf '%q\n' *). Это будет экранировать пробелы, символы новой строки и т. Д., Если в ваших именах файлов есть какие-то странные символы. (Спасибо @muru в чате за указание на это !)

Дверная ручка
источник
2
При работе с неизвестными данными вы должны ВСЕГДА использовать '%s'\nи / или любым другим постоянным текстом, который вы хотите). Например, попробуйте команды touch '%.0s' foo bar; ls; printf -- *. И наоборот, я не понимаю, зачем вам это нужно, --когда у вас есть '%s\n'строка формата.
G-Man говорит «Восстановить Монику»
@ G-Man Хороший вопрос! Спасибо, я пропустил ненужное --с форматной строкой, и я отредактировал свой пост, чтобы обратиться к другой вещи.
Дверная ручка
-nФайла честно не должно быть проблемой вообще для POSIX-2001 + echo- на SUSv3 системах echoутилита требуется не принимать какие - либо варианты вообще. bashОднако echoнекоторые и некоторые другие обрабатывают эту опцию, но bashмогут быть скомпилированы с опцией сборки, --enable-xpg-echo-defaultчтобы она всегда работала правильно. Правильное поведение echo, тем не менее, означает всегда интерпретировать экранирование обратной реакции в своих аргументах. Таким образом, любое имя файла с экранированием в стиле C не будет записано в вывод с верностью - echoпереведет его.
mikeserv
2
пожалуйста, пожалуйста, все должны прекратить рекомендовать '-', когда faq unix более 10 лет объясняет, что использование "./" лучше и более переносимо (работает со всеми программами, даже со многими, которые не обрабатывают) - ')
Оливье Дюлак
1
@OliverDulac - даже это не помогло бы echo.
mikeserv
8

Вы , вероятно , следует использовать fileи unameутилиты , чтобы получить лучшее представление о том, что происходит, черт с вашей машиной. Ваша ошибка указывает на двоичный исполняемый файл, скомпилированный для архитектуры системы, несовместимой с той, на которой он вызывается.

На моей машине:

uname -m; file /bin/ls

... печать ...

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

... потому что с миром все в порядке. Тем не менее, вот несколько команд, которые запускаются с моего планшета Android при sshподключении к моему рабочему столу ...

#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
источник
Это отличный ответ, который охватывает один сценарий и устраняет потенциальную причину.
Пранаб
неправильно прочитал ^^ извините. почему бы просто не скопировать и использовать файл? почему весь этот homedir? scp на рабочий стол, файл на нем и bash ./it?
Оливье Дюлак
@OlivierDulac -ммм .. я не уверен, что понял, о чем ты спрашиваешь. Дело в HOME=том, что я могу просто сделать ~кучу раз вместо ./arm_ls - для удобства. Весь смысл упражнения заключается в том, что я не могу использовать двоичный файл arm на моем рабочем столе x86, и я хотел, чтобы выходные данные fileпоказали, что это совсем другой вид двоичного файла, чем родной для sydtem - который показан вверху. И поэтому вместо shpw целой кросс-компиляции я выбрал cpy несовместимый двоичный файл, который был у меня в руках на моем компьютере разработчика для моего устройства x86, и показал результаты и как вызвать bashошибку.
mikeserv
1
о, это было просто, чтобы сохранить несколько печатать? хорошо, но я думаю, что это делает это более запутанным, чем это должно быть (это не codegolf ^^)
Оливье Дюлак
1
@OliverDulac - конечно, это не код золота, но это удобно, это совсем не двусмысленно, и я ненавижу печатать пальцем.
mikeserv
5

Используя bash (или многие другие оболочки), вы можете использовать табуляцию для вывода списка файлов:

$ thisisnotacommand ./public_html/<TAB>
acc/              papers/           android/          l/
sdr/              blast             formalcss.html    switch/
busy/             formalcss.tar.gz  others/           together.jpg
user1998586
источник
3

Если вам нужно что-то более похожее ls -l(размер файла, права доступа, владелец, временные метки и т. Д.), Тогда stat -- *может быть полезно:

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

В качестве альтернативы, если все, что вы хотели сделать, - это ошибка ls , попробуйте slвместо этого . ;-) (продолжайте - попробуйте ... возможно, вам придется установить его)

Цифровая травма
источник
3

Существует очень похожая утилита, доступная во многих системах:

dir

Согласно информационным страницам это эквивалентно ls -C -b, но это отдельный двоичный файл.

Преимущество использования dir (вместо, например, системы завершения оболочки) заключается в доступности различных опций, таких как сортировка, отображение скрытых файлов, раскраска и т. Д., Как в стандартной lsпрограмме.

Кстати, я думаю, его название происходит от системы Windows (или, скорее, DOS).

jimmij
источник
1

использование

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

источник