路径中的可执行文件,可通过哪个路径找到,但是如果没有完全限定的路径就无法执行?


12

我遇到了一个看起来很奇怪的shell问题,在$ PATH中有一个命令,该命令(shell(ksh,在Linux上运行)似乎胆怯地拒绝调用)。在不完全限定命令的情况下,我得到:

#  mycommand
/bin/ksh: mycommand: not found [No such file or directory]

但是可以通过以下方式找到文件:

#  which mycommand
/home/me/mydir/admbin/mycommand

我还明确地在$ PATH中看到该目录:

#  echo $PATH | tr : '\n' | grep adm
/home/me/mydir/admbin

该位置的exe似乎正常:

#  file /home/me/mydir/admbin/mycommand
/home/me/mydir/admbin/mycommand: setuid setgid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped

# ls -l mycommand  
-r-sr-s--- 1 me mygroup 97892 2012-04-11 18:01 mycommand

如果我使用完全限定的路径显式运行它:

#  /home/me/mydir/admbin/mycommand

我看到了预期的输出。肯定会使这里的外壳有些混乱,但我茫然不知所措?

编辑:查找看起来像一个类似的问题:使用路径运行时,二进制文件将不会执行。例如> ./ program无效,但> program正常

我还在$ PATH中测试了多个这样的命令,但只找到了一个:

# for i in `echo $PATH | tr : '\n'` ; do test -e $i/mycommand && echo $i/mycommand ; done
/home/me/mydir/admbin/mycommand

编辑2:

从今天早上开始,问题消失了,现在我可以执行可执行文件了。

可以认为这可以验证注销和登录的建议,但是我昨晚这样做并没有成功。该注销/登录也应该等效于运行建议的'hash -r'命令(该fwiw似乎也是ksh内置的,而不仅仅是bash内置的)。

针对某些答案:

  • 这是可执行文件,而不是脚本(请参阅文件命令输出中的ELF参考)。

  • 我认为一点努力不会有所帮助。最终迫使该命令执行完全限定的命令。我想我可以在当前shell上完成strace附加,但是由于我再也无法复制,因此没有必要尝试这样做。

  • $ PATH中没有分号。由于我无法再进行复制,因此我不会用完整的$ PATH弄乱这个问题。

  • 如建议的那样,尝试另一个shell(即bash)将是我也尝试过的事情。随着问题的解决,我现在不知道这是否会有所帮助。

还建议我检查目录权限。这样做,对于直到该目录的每个目录,我都会看到:

# ls -ld $HOME $HOME/mydir $HOME/mydir/admbin
drwxr-xr-x 10 me root    4096 2012-04-12 12:20 /home/me
drwxrwsr-t 22 me mygroup 4096 2012-04-12 12:04 /home/me/mydir
drwxr-sr-x  2 me mygroup 4096 2012-04-12 12:04 /home/me/mydir/admbin

$ HOME目录所有权被弄乱了(不能是根组)。那可能会导致其他问题,但是我不知道它将如何导致这一问题。


2
您的脚本功夫真棒。
杰夫·弗兰

2
我知道这听起来过于简单,但我曾经遇到过同样的问题,结果证明它是用作分号而不是冒号的分号。
John Gardeniers

您可以提供整个PATH设置吗?
杰森·亨特利

这是一个写得很好的问题。
gWaldo

可能是外壳的缓存?
Michael Slade

Answers:


1

您可能需要在$PATHusing中更新shell的项目缓存hash -r


$ apropos hash | grep ksh - 没有。您已经回答了bash内置问题,但这不是问题所在的外壳。
杰夫·弗兰

1

同样,在这种情况下,通过将其可执行文件作为参数传递给动态链接程序来检查调用程序时会发生什么(在某些系统上,当setuid / setgid可能拒绝这样做)。

两种情况的ldd(1)输出也可能显示出来。可执行文件上的“没有这样的文件或目录”确实意味着找不到在可执行文件中指定的动态链接器(想象其中的可执行文件的ELFin格式为#!/ lib / ld-linux.what.so.ever)。

这种行为使人们目不转睛地见证了libc5时代的结束,现在偶尔会傻眼于混合i386 / amd64时代的人们,他们以不同的方式狂野地支持两个库集。

可执行文件与$ PWD中的相对RPATH?

PS另一个问题与MacOSX有关,它可能使用dyld而不是libc提供的链接器。非常不同的动物。


0

好吧,我没有答案。我确实证明了一些事情,并认为以后可以补充:

  • 创建了一个测试文件-您的权限显示它是setuid和可执行文件。
  • 尝试使用nosuid将其设置在安装点上:仍在运行
  • 尝试使用noexec将其设置在安装点上:给出了另一个错误

因此,从所有方面来看,我仍然感到困惑。只是出于咧嘴笑,这是一个与外壳相关的错误,您可以尝试使用其他外壳吗?


0

我猜您的脚本在#!之后没有有效的shell。例如,在某些较旧的SCO系统上,带有#!/ bin / bash的脚本不起作用,因为bash实际上位于/ usr / bin / bash中。哑巴,但SCO几乎因为某种原因而死了,不是吗?

检查您的外壳,并确保其指向真实的二进制文件/脚本。

编辑:它不会告诉您它是脚本还是二进制文件,但是假设您的'ls -l'输出正确,那么您可能没有93kbyte脚本...所以这可能是二进制文件,这意味着我的答案是完全不正确。

您是否尝试过注销并重新登录?我知道如果我使用/ usr / bin中的二进制文件,然后从源代码安装/ usr / local / bin版本,系统仍会尝试执行原始的二进制文件,直到我注销并重新登录。


它是可执行文件,而不是脚本(请参阅问题文件中的ELF信息)。是的,我已经登出和英寸
Peeter Joot

0

我的猜测:

  • 您有一个名为的别名mycommand。例如:

    alias mycommand=something
    
  • 您有一个名为的函数mycommand。例如:

    mycommand() { something; }
    

下次遇到此问题时,请尝试运行command -V mycommand以查看Shell认为的命令类型mycommand


这两个命令都不是这种情况。
Peeter Joot

0

没有答案,只有一些想法:

  1. 检查文件名是否包含空格;使用制表符补全并将其用作参数时,将默默地忽略它。
  2. 在目录中尝试另一个脚本/程序。
  3. 尝试跟踪外壳程序以尝试执行脚本,并查看其中断位置。

0

我遇到了完全相同的问题,但找不到答案,因为原始海报的问题已解决。但这对我不起作用,我最终设法找到了问题所在。因此,我将以下内容作为原始帖子的答案。

我面临的症状如下。/ my / home目录中有一个脚本(myscript.pl)。现在尝试运行它:

> /my/home/myscript.pl
myscript.pl:  permission denied.

文件的经过验证的权限(设置了执行标志)。已验证$ PATH(尽管应该没有问题)。

所以,然后我尝试(在验证脚本上设置了可执行标志之后):

> cd /my/home/
> ./myscript.pl:  permission denied.

嗯...所以脚本可能没有调用正确的脚本语言(在这种情况下为perl)。该脚本的顶部具有正确的魔术:

#!/usr/bin/perl

/ usr / bin / perl确实存在并且可以工作。因此,以下调用可以正常工作。

/usr/bin/perl myscript.pl

标签自动完成功能不会显示该文件(既不在中tcsh也不在中bash)。

这真的让我失望了。然后想起几个月前,我的硬盘崩溃了,实验室里的年轻系统管理员重新安装了系统。以为他可能搞砸了分区上的权限。实际上,在中/etc/fstab,缺少exec权限!

/dev/sda1    /my     /ext4      rw,user

代替

/dev/sda1    /my     /ext4      rw,user,exec

通过更改/etc/fstab和重新安装来解决此问题:

mount -v -o remount /my

这样就完全解决了问题。我的猜测是,原始发布者的问题可能发生了类似的事情,除了权限问题是间歇性的(例如,如果发生了临时更改,则可能需要重新启动才能解决)。


-1

并不是一个完整的答案,而是想报告我的经历,因为我遇到的问题与提问者完全一样,并认为这可能会帮助将来的用户遇到同样令人发疯的问题。我可以选择哪个文件,并在路径中查看它,甚至通过提供完整路径来执行它,但否则无法执行。但是,就我而言,它仅在子外壳程序内发生(即,从脚本执行时,在这种情况下,有几个嵌套的子外壳程序)。我可以从命令行运行它。

在嵌套脚本中的命令之前,我已打印出命令,例如echo $(哪mycommand)

mycommand:/ home / me / bin / mycommand

然后,我尝试从父脚本执行它:

/ home / me / bin / some_parent_script [72]:mycommand:找不到[没有这样的文件或目录]

就像发问者一样,我无法诊断问题的根源。我的PATH看起来正确,可以访问,并且哈希没有显示mycommand的任何先前条目。第二天,我登录后,一切恢复了正常。现在,我将在这里指出,在我看到重新安装挂架的问题之前,发生了一个已知的系统问题。也许这是一个线索?

如果在日志文件之后没有日志文件表明发生了这种情况,那么我不认为这是可能的!多亏了提问者,我才不再发疯!

PS:我认为user226160的问题与报告者没有完全相同的问题,但是听起来很相关,并且对安装理论很有帮助。

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.