信頼できる実行可能ファイルをスクリプトで実行しようとしています。
バイナリ実行可能ファイルをコピーしました/bin/ip
をTools
というディレクトリに移動します。
バイナリの名前をeip
に変更しました。
ディレクトリツールに移動し、実行可能ファイルeip
を実行しようとしました。
# ./eip addr list
エラーをスローします:object "ip" is unknown , try "ip help."
これに対処するには?
ローカルの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文字を超える場合は、残りの文字を操作対象のオブジェクトの名前として解釈するように設計されているようです。おそらくこれは、ip
、iplink
、ipaddr
などの名前を持つ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 "$@"
_