シェルからライブラリコマンドを実行するには?

シェルからライブラリコマンドを実行するには?

単純に文字列の長さ(つまり、ハッシュ値)を計算したいと思います。だから端末を開き、次のようにします。

$ apropos length

(3)これにより、最後に追加または追加された複数のコマンド/関数が返されます。(3ssl)この意味についての情報を提供してくださいsection numbers

3   Library calls (functions within program libraries)

好奇心が強いので、このコマンドをすべて試しました(少なくとも1つは機能します)。

strcspn (3)          - get length of a prefix substring
strlen (3)           - calculate the length of a string
strnlen (3)          - determine the length of a fixed-size string
strspn (3)           - get length of a prefix substring
wcslen (3)           - determine the length of a wide-character string
wcsnlen (3)          - determine the length of a fixed-size wide-character string

すべてのコマンドで同じエラーが発生する

$ strnlen HelloWorld 
$ strnlen: command not found

うんシェルで文字列の長さを見つける方法wc -mそして他の回避策expr length

しかし、ここには2つの質問があります。

  1. 使い方どのlibrary calls (3)殻の中?
  2. 他のコマンドなしでライブラリ呼び出しのみを使用して文字列の長さを計算するには?

注:質問は一般的なケースlibrary callsとシェルでの使用法に焦点を当てています。これにより、最初の質問に対する回答がより重要になります。

ベストアンサー1

あなたはできるしてはいけないできるだけしてください。コサロナンダの答え現在の作業に適しており、問題を説明します。具体的にどのように使うのか尋ねたのでどのしかし、端末内でライブラリを呼び出す方法はいくつかあります。


これTiny Cコンパイラ(tcc)サポート-runフラグこれにより、小さなプログラムを作成してCコードを(実際に)解釈することができます。できる端末内のすべてのライブラリ呼び出しは単一の呼び出しとして使用できます。

strnlen次のように関数を実行できます。

$ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", strnlen(argv[1], 1024));}') "Hello world"
11

これは以下を使用します。プロセスの交換他のオプションを含むすべての結果を含むように見えるBash、zsh、およびその他のシェルからtcc読み取るファイルを提供します。echo

これを生成する関数を作成できます。

call_library_function_s_i() {
    func=$1
    shift
    tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", '$func'(argv[1]));}') "$*"
}
$ call_library_function_s_i strlen hello world

(ここでは単項関数string->intを使用していますstrlen。それぞれの数量と戻り値の型に別々の関数が必要です)。


別のオプションはバッシュctypes.shプラグインTavis Ormandyによって書かれdlopenましたdlsym。たとえば、次のように使用できます。

$ dlcall -r uint64 strlen "hello world"

期待どおりに関数を呼び出します。

これは、「ターミナルで」これを行う最も直接的な方法ですが、ディストリビューションにパッケージとして含まれていない可能性が高いため、手動でインストールする必要があります(重要)。ここにいくつかの情報がありますctypes.sh自社ホームページから引用人々がこれについてどのように感じるかについての全体的な印象を与えてください。

  • 「本当に逆重い」
  • 「これは止まらなければならない」
  • 「とても遠くに行きました」

他のシェルにも同様のツールがあるかもしれませんが、それについてはわかりません。理論的には、単純な場合に正確にこれを実行するスタンドアロンコマンドがあってはならない理由はありませんが、まだ見つかっていないという事実に少し驚きました。


…だから一つ作ったんです! dlcallコマンドラインからライブラリ関数を呼び出すことができます。:

$ dlcall strnlen "hello world" 6
$ dlcall sin 2.5
$ dlcall strchr "hello world" -c ' '

限られた機能プロトタイプセットをサポートし、まだ安定性や弾力性が劣りますが、現在としては存在します。


たとえば、次のものを使用することもできます。Pythonとpython -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello worldしかし、これは確かに最も簡単な方法ではありません。 Perl、Ruby、その他の言語でも同様の機能を使用できます。


したがって、あなたの質問に対する答えは次のとおりです。

  1. 上記のいずれかの方法を使用してください。
  2. あなたするライブラリから起動するには、別のコマンドが必要なソフトウェア、またはシェルに接続するソフトウェアが必要です。

通常、これを他の方法で実行することはほぼ確実に優れています。

おすすめ記事