当“ ls”命令不起作用时该怎么用?


15

我尝试使用该ls命令并出现错误:

bash: /bin/ls: cannot execute binary file

我可以使用什么代替该命令?


也许您搞砸了自己libc*so或您的ld-linux*so
Basile Starynkevitch 2015年

31
就个人而言,除非进行一些古怪的思想实验,否则我将专注于修复系统。
Faheem Mitha 2015年

2
@BasileStarynkevitch从未听说过它,但是Busybox普遍存在并且可以介入。–
muru

8
...系统救援CD?
2015年

1
一个问题解决的实际问题,在这种情况下是superuser.com/questions/435988。正如所暗示的,sash在Ubuntu Linux上,在FreeBSD ports树中的shell /窗扇,在Gentoo包中以及在其他地方(包括直接从其作者那里获得)都可以使用
JdeBP 2015年

Answers:


32

您可以使用echoor find命令代替ls

echo *

要么:

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

7
我会使用echo -- *
Edward Torvalds

9
@Invoker:如果您碰巧-n在当前目录中有一个文件,它将被解释为一个标志,而不是要回显的东西。
MvG 2015年

2
那将是touch ./-n
Basile Starynkevitch 2015年

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' *

printfecho在这种情况下优于,因为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)使用了格式字符串,并向其传递了文件名(如前所述,通过globing进行了扩展)。

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实用程序必须不接受任何选项。bashecho和其他一些确实可以处理该选项,但是bash可以使用build选项进行编译--enable-xpg-echo-default以使其始终正确运行。但是,正确的行为echo意味着始终在其参数中解释反冲转义。因此,任何具有C样式转义符的文件名都不会写入带有保真度的输出- echo会对其进行翻译。
mikeserv

2
请,请,当unix常见问题解答已经有10多年的历史了,那么每个人都应该停止推荐'-',因为使用“ ./”更好,更可移植(可与所有程序一起使用,甚至包括许多不处理的程序) ')
Olivier Dulac

1
@OliverDulac-甚至不会符合规范echo
mikeserv

8

您可能应该使用fileuname实用程序来更好地了解计算机到底发生了什么。您的错误表明为系统体系结构编译的二进制可执行文件与其调用的体系结构不兼容。

在我的机器上:

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

这是一个很好的答案,它涵盖了一种情况并解决了潜在的根本原因。
普拉纳布(Franab)2015年

误读^^对不起。为什么不只是复制和使用文件?为什么整个homedir的事情?scp到桌面,文件和bash ./it?
Olivier Dulac

@OlivierDulac -hmm ..我不确定我能确切地知道你在问什么。该HOME=事情是这样我就可以做~了一堆的时代,而不是./arm_ls -为了方便。该练习的全部要点是,我无法在x86桌面上使用arm二进制文件,并且我希望输出file来表明它是与系统本机二进制文件非常不同的一种二进制文件-如上图所示。因此,与其选择整个交叉编译,不如说我将自己的手臂开发人员可以使用的不兼容的二进制文件cpy转换为x86设备,并显示了结果以及如何解决该bash错误。
mikeserv

1
哦,这只是节省了一些打字?好的,但是我认为它比应有的更令人困惑(不是codegolf ^^)
Olivier Dulac

1
@OliverDulac-当然,它不是黄金代码,但是它很方便,一点也不歧义,我讨厌用拇指打字。
mikeserv

5

使用bash(或许多其他shell),可以使用制表符补全列出文件:

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

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程序一样(而不是例如shell补全系统)不同的选项,例如排序,显示隐藏文件,着色等。

顺便说一句,我想它的名字来自Windows(或称Dos)系统。


1

采用

 echo -- *
    find . -printf "%M\t%u\t%g\t%p\n"
    ls -C -b
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.