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?
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 "$@"