web-dev-qa-db-fra.com

Erreur: l'objet "ip" est inconnu, essayez "ip help"

J'essaie d'exécuter des exécutables approuvés via un script.

J'ai copié l'exécutable binaire /bin/ip dans un répertoire appelé Tools.

J'ai renommé le binaire en eip.

J'ai navigué vers les outils d'annuaire et essayé d'exécuter l'exécutable eip.

# ./eip addr list

Il renvoie une erreur: object "ip" is unknown , try "ip help."

Comment y faire face?

1
sudheer

Si vous conservez votre ip exécutable local appelé ip, et pas quelque chose de plus long, vous pouvez éviter ce problème particulier. Si vous le renommez en un autre nom long d'un ou deux caractères, cela fonctionnera également très bien - le problème ne se produit que si son nom comporte trois caractères ou plus. Cela peut sembler étrange ... alors lisez la suite pour plus de détails ...

Lorsque j'exécute une copie de /bin/ip appelé eip, j'obtiens un message d'erreur avec p (plutôt que ip) comme objet inconnu:

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

Je me demande si la même chose t'arrive? (Pourrait-il y avoir une faute de frappe dans votre question?) Même si ce n'est pas le cas, je soupçonne fortement que le comportement de votre machine est lié à ce que je vois.

J'ai trouvé que lorsque j'ai renommé ip en plus de deux caractères, cela m'a donné une erreur "objet inconnu" sur le reste des caractères:

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 ne semble pas expliquer ce comportement étrange, mais j'ai remarqué que le premier argument sans option de ip est techniquement appelé un objet:

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 }

....

J'ai donc essayé de changer les caractères, après les deux premiers, en ces noms d'objet:

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
....

Il semble donc que ip est conçu pour vérifier le nom avec lequel il a été invoqué et s'il contient plus de deux caractères, pour interpréter les caractères restants comme le nom de l'objet sur lequel opérer. C'est probablement le cas pour que les copies et les liens symboliques de ip avec des noms comme iplink, ipaddr, ipaddrlabel, etc., puissent agir comme si ip link, ip addr, ip addrlabel, et ainsi de suite ont été exécutés en conséquence.

Pour vérifier cela, j'ai regardé le code source. Le iproute2 le package fournit /bin/ip, donc j'ai cherché cela et je l'ai trouvé fourni par le paquet source du même nom . (C'est souvent mais pas toujours le cas.) Dans l'onglet code , I sélectionné une branche et parcouru le code , en entrant le répertoire ip et en examinant ip.c.

J'ai regardé dans la fonction main, car c'est là que la plupart des programmes C commencent à s'exécuter. C'est la fonction qui commence:

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

Comme de nombreuses fonctions main de nombreux programmes, elle consiste en grande partie à traiter pour options de ligne de commande . Mais en dessous, il y a du code pour gérer les différentes façons dont ip peut être exécuté, et l'un d'eux est lorsque son nom comporte plus de deux caractères:

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

Cool! (Un peu bizarre - mais cool.)


La solution la plus simple et la meilleure consiste probablement à conserver votre copie de ip appelée ip, ou un autre nom à un ou deux caractères. En lui donnant le même nom que la copie de ip dans /bin (et pointé par le /sbin/ip symlink) ne devrait pas poser de problème - votre script fournit déjà un chemin vers l'exécutable spécifique que vous souhaitez exécuter.

Cependant, vous souhaiterez peut-être que les utilisateurs puissent invoquer votre copie de ip avec une commande comme eip-- par exemple, afin qu'ils puissent avoir une commande distincte à placer dans des répertoires dans leur PATH. Ceci est généralement réalisé avec un lien symbolique, mais cela échouera ici pour la même raison que l'appel de la copie eip a échoué en premier lieu:

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

(J'ai créé un lien symbolique vers le /bin/ip, mais la même chose se produit lorsque vous créez un lien symbolique vers une copie distincte.)

La solution consiste à écrire un script wrapper (nommé eip, ou ce que vous voulez) qui invoque ip, en passant ses arguments. Le fichier de script peut ressembler à ceci:

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