Se você mantiver seu executável ip
local chamado ip
, e não algo mais longo, poderá evitar esse problema específico. Se você renomeá-lo para outro nome longo de um ou dois caracteres, isso também funcionará bem - o problema só acontece se seu nome tiver três ou mais caracteres de comprimento. Isso pode parecer estranho ... então leia mais para detalhes ...
Quando executo uma cópia de /bin/ip
chamado eip
, recebo uma mensagem de erro com p
(em vez de ip
) como o objeto desconhecido:
Object "p" is unknown, try "ip help".
Eu estou querendo saber se o mesmo está acontecendo com você? (Pode haver um erro de digitação em sua pergunta?) Mesmo se não, eu suspeito strongmente que o comportamento em sua máquina está relacionado ao que estou vendo.
Descobri que, quando renomei ip
para algo maior que dois caracteres, ocorreu um erro "objeto desconhecido" sobre o restante dos caracteres:
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
não parece explicar esse comportamento estranho, mas notei que o primeiro argumento não-opcional para ip
é tecnicamente chamado de objeto :
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 }
....
Então, tentei alterar os caracteres, depois dos dois primeiros, para esses nomes de objeto:
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
....
Portanto, parece que ip
foi criado para verificar o nome com o qual foi invocado e, se contiver mais de dois caracteres, para interpretar os caracteres restantes como o nome do objeto no qual operar. Provavelmente, isso faz com que cópias e links simbólicos de ip
com nomes como iplink
, ipaddr
, ipaddrlabel
e assim por diante possam agir como se ip link
, ip addr
, ip addrlabel
e assim em correspondentemente foram executados.
Para verificar isso, examinei o código-fonte. O pacote iproute2
fornece /bin/ip
, então eu procurei por e descobri que ele é fornecido por < href="https://launchpad.net/ubuntu/+source/proute2"> o pacote fonte do mesmo nome . (Isso é sempre, mas nem sempre é o caso). Em a guia de código , eu selecionou um branch e pesquisou o código , digitando o diretório ip
e examinando ip.c
.
Eu olhei na função main
, pois é onde a maioria dos programas em C começa a ser executada. Esta é a função que começa:
int main(int argc, char **argv)
{
Como muitos programas ' main
functions, consiste basicamente em processamento para opções de linha de comando . Mas abaixo disso, há código para lidar com as várias formas em que ip
pode ser executado, e uma delas é para quando seu nome tiver mais de dois caracteres :
if (strlen(basename) > 2)
return do_cmd(basename+2, argc, argv);
Legal! (Meio estranho - mas legal.)
A solução mais simples e melhor provavelmente é apenas manter sua cópia de ip
chamada ip
ou algum outro nome de um ou dois caracteres. Dar o mesmo nome que a cópia de ip
em /bin
(e apontada pelo link /sbin/ip
) não deve ser um problema - seu script já está fornecendo um caminho para o executável específico que você deseja executar.
No entanto, talvez você queira que os usuários invoquem sua cópia de ip
com um comando como eip
- por exemplo, para que possam ter um comando separado para colocar em diretórios em seus PATH
. Isso é comumente obtido com um link simbólico, mas isso falhará aqui, pelo mesmo motivo que, em primeiro lugar, a cópia eip
falhou:
ek@Io:~$ ln -s /bin/ip eip
ek@Io:~$ ./eip
Object "p" is unknown, try "ip help".
(Eu fiz um link simbólico para o /bin/ip
do meu sistema, mas o mesmo acontece quando você liga simbolicamente a uma cópia separada.)
A solução é escrever um script wrapper (chamado eip
, ou o que você quiser) que invoque ip
, passando seus argumentos. O arquivo de script pode ser assim:
#!/bin/sh
/path/to/your/ip "$@"