web-dev-qa-db-ja.com

エラー:オブジェクト「ip」は不明です。「ipヘルプ」を試してください

信頼できる実行可能ファイルをスクリプトで実行しようとしています。

バイナリ実行可能ファイルをコピーしました/bin/ipToolsというディレクトリに移動します。

バイナリの名前をeipに変更しました。

ディレクトリツールに移動し、実行可能ファイルeipを実行しようとしました。

# ./eip addr list

エラーをスローします:object "ip" is unknown , try "ip help."

これに対処するには?

1
sudheer

ローカルのip実行可能ファイルipを保持し、それ以上長くしない場合は、この特定の問題を回避できます。名前を他の1文字または2文字の長い名前に変更した場合も、正常に機能します。問題は、名前の長さが3文字以上の場合にのみ発生します。これは奇妙に思えるかもしれません...詳細については読んでください...

eipという_/bin/ip_のコピーを実行すると、不明なオブジェクトとしてpではなくipを含むエラーメッセージが表示されます。

_Object "p" is unknown, try "ip help"._

同じことがあなたに起こっているのかしら? (あなたの質問にタイプミスがあるかもしれませんか?)そうでない場合でも、あなたのマシンでの動作は私が見ているものに関連していると強く思います。

ipの名前を2文字より長い名前に変更すると、残りの文字に関する「不明なオブジェクト」エラーが発生することがわかりました。

_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 }

...._

したがって、最初の2つの文字を次のオブジェクト名に変更してみました。

_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は、呼び出された名前を確認し、2文字を超える場合は、残りの文字を操作対象のオブジェクトの名前として解釈するように設計されているようです。おそらくこれは、ipiplinkipaddrなどの名前を持つipaddrlabelのコピーとシンボリックリンクが、_ip link_、_ip addr_、_ip addrlabel_などが対応して実行されました。

これを再確認するために、ソースコードを確認しました。 _iproute2_パッケージは_/bin/ip_を提供するので、 それを検索 し、 同じ名前のソースパッケージ によって提供されることがわかりました。 (これは多くの場合ですが、常にそうとは限りません。) コードタブ 、I ブランチを選択 および コードを参照 、入力 ipディレクトリ_ip.c_を調べます。

main関数を調べました。これが、ほとんどのCプログラムが実行を開始する場所だからです。これが始まる関数です:

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

多くのプログラムのmain関数と同様に、これは主に コマンドラインオプション の処理で構成されています。しかしその下には、ipを実行するさまざまな方法を処理するコードがあり、そのうちの1つはその名前が2文字を超える場合です。

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

涼しい! (奇妙な奇妙な、しかしクールです。)


最も単純で最良の解決策は、ipと呼ばれるipのコピー、またはその他の1文字または2文字の名前を保持することです。 _/bin_内のipのコピーと同じ名前を付けても(_/sbin/ip_シンボリックリンクによってポイントされていても)問題ありません-スクリプトはすでに実行する特定の実行可能ファイル。

ただし、たとえば、ユーザーがipのコピーを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 "$@"_
1
Eliah Kagan