我遇到了一个奇怪的 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
我看到了预期的输出。这里肯定有什么东西让 shell 感到困惑,但我不知道那是什么?
编辑:找到一个类似的问题:使用路径运行时,二进制文件不会执行。例如 >./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 参考)。
我认为 strace 不会有帮助。这最终会强制命令完全合格地执行。我想我可以在当前 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 目录所有权混乱(不应为 root 组)。这可能会导致其他问题,但我不明白它是如何导致这个问题的。
答案1
$PATH
您可能需要更新 shell 中正在使用的项目缓存hash -r
。
答案2
另外,在这种情况下,检查当通过将程序的可执行文件作为参数传递给动态链接器来调用程序时发生的情况(在某些系统上 setuid/setgid 时可能会拒绝这样做)。
两种情况下的 ldd(1) 输出也可能具有启发性。可执行文件上的“没有这样的文件或目录”实际上意味着无法找到可执行文件中指定的动态链接器(想象一下可执行文件中有一个 ELFin 形式的 #!/lib/ld-linux.what.so.ever 内部)
这种行为让那些见证了 libc5 时代终结的人们感到震惊,而现在,这种行为偶尔也会让处于混合 i386/amd64 时代的人们感到震惊,因为他们使用不同的方式在野外支持两套库。
可执行文件中的相对 RPATH 与 $PWD?
PS 另一个问题与 MacOSX 有关,它可能使用 dyld 而不是 libc 提供的链接器。完全不同的动物。
答案3
好吧,我没有答案。我确实证实了一些事情,我想我以后可能会补充一些:
- 创建了一个测试文件——您的权限表明它是 setuid 且可执行的。
- 尝试使用 nosuid 将其设置在挂载点上:仍然运行
- 尝试使用 noexec 将其设置在挂载点上:给出了不同的错误
所以,总而言之,我仍然感到困惑。只是为了开个玩笑,万一这是一个与 shell 相关的错误,你能用不同的 shell 试试吗?
答案4
我的猜测:
您有一个名为 的别名
mycommand
。例如:alias mycommand=something
你有一个名为 的函数
mycommand
。例如:mycommand() { something; }
下次遇到此问题时,请尝试运行command -V mycommand
以查看 shell 认为mycommand
是什么类型的命令。