Erro: o objeto “ip” é desconhecido, tente “ip help”

1

Estou tentando executar executáveis confiáveis por meio de um script.

Eu copiei o executável binário /bin/ip para um diretório chamado Tools .

Eu renomei o binário para eip .

Eu naveguei para as ferramentas de diretório e tentei executar o arquivo executável eip .

# ./eip addr list

Ele lança um erro: object "ip" is unknown , try "ip help."

Como lidar com isso?

    
por sudheer 02.04.2015 / 02:24

1 resposta

1

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 "$@"
    
por Eliah Kagan 03.04.2015 / 06:35