错误:对象“ip”未知,请尝试“ip help”

错误:对象“ip”未知,请尝试“ip help”

我正在尝试通过脚本运行受信任的可执行文件。

我将二进制可执行文件复制/bin/ip到名为的目录中Tools

我将二进制文件重命名为eip

我已导航到目录工具并尝试运行可执行文件eip

# ./eip addr list

它会引发一个错误:object "ip" is unknown , try "ip help."

如何处理这个问题?

答案1

如果您将本地ip可执行文件命名为ip,而不是更长的名称,则可以避免此特定问题。如果您将其重命名为其他一个或两个字符长的名称,也可以正常工作 - 只有当其名称长度为三个或更多字符时才会出现问题。这可能看起来很奇怪...请继续阅读以了解详细信息...

/bin/ip当我运行名为的副本时eip,我收到一条错误消息,其中p(而不是ip)作为未知对象:

Object "p" is unknown, try "ip help".

我想知道您是否遇到了同样的情况?(您的问题中可能存在拼写错误吗?)即使没有,我也强烈怀疑您机器上的行为与我所看到的情况有关。

我发现当我将其重命名ip为任何长度超过两个字符的内容时,它会给我一个关于其余字符的“未知对象”错误:

ek@Io:~$ cp /bin/ip abc
ek@Io:~$ ./abc
Object "c" is unknown, try "ip help".
ek@Io:~$ mv abc foobar
ek@Io:~$ ./foobar
Object "obar" is unknown, try "ip help".
ek@Io:~$ mv foobar 12345
ek@Io:~$ ./12345
Object "345" is unknown, try "ip help".

man ip似乎无法解释这种奇怪的行为,但我确实注意到,第一个非选项参数在ip技术上被称为目的

SYNOPSIS
       ip [ OPTIONS ] OBJECT { COMMAND | help }

       ip [ -force ] -batch filename

       OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |
               tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm |
               netns | l2tp | tcp_metrics }

....

因此,我尝试将前两个字符之后的字符更改为以下对象名称:

ek@Io:~$ mv 12345 12addr
ek@Io:~$ ./12addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
....
ek@Io:~$ mv 12addr XXrule
ek@Io:~$ ./XXrule 
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default
ek@Io:~$ mv XXrule ipl2tp
ek@Io:~$ ./ipl2tp 
Usage: ip l2tp add tunnel
          remote ADDR local ADDR
....

因此,它似乎ip被设计用来检查调用它的名称,如果名称包含两个以上的字符,则将其余字符解释为要操作的对象的名称。这可能是为了让ip名称为iplinkipaddripaddrlabel等的 的副本和符号链接可以表现为ip linkip addrip addrlabel等相应地运行。

为了再次确认这一点,我查看了源代码。该iproute2软件包提供/bin/ip搜索过并发现它是由同名源码包(这种情况经常发生,但并非总是如此。)代码标签, 我选择一个分支浏览代码,输入目录ip并检查ip.c

我查看了该main函数,因为大多数 C 程序都是从该函数开始运行的。以下是该函数的开头:

int main(int argc, char **argv)
{

与许多程序的main功能一样,它主要包括处理命令行选项。但下面有代码来处理ip可能运行的各种方式,其中之一是当其名称长度超过两个字符时

if (strlen(basename) > 2)
        return do_cmd(basename+2, argc, argv);

很酷!(有点奇怪——但很酷。)


最简单、最好的解决方案可能就是保留ip名为的副本ip,或者其他一个或两个字符的名称。赋予它与ipin副本相同的名称/bin(并由符号链接指向/sbin/ip)应该没有问题——您的脚本已经提供了要运行的特定可执行文件的路径。

但是,您可能希望用户能够ip使用 --for 之类的命令来调用您的副本eip,这样他们就可以使用单独的命令将目录中的目录放入其中PATH。这通常通过符号链接实现,但在这里会失败,原因与调用副本eip失败的原因相同:

ek@Io:~$ ln -s /bin/ip eip
ek@Io:~$ ./eip
Object "p" is unknown, try "ip help".

(我建立了到我的系统的符号链接/bin/ip,但是当您符号链接到单独的副本时也会发生同样的情况。)

解决方案是编写一个包装器脚本(命名为eip,或任何你喜欢的名字),该脚本调用ip,并传递其参数。脚本文件可能如下所示:

#!/bin/sh
/path/to/your/ip "$@"

相关内容