Linux 環境でいくつかのバイナリを使用しており、ユーザー入力をスクリプト化しようとしています。たとえば、最初のプログラム prog1.c の場合:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
fgets(buffer, 31, stdin);
printf("Your input: %s\n", buffer);
i++;
}
}
prog1 を実行してコンソールから直接入力するか、入力をスクリプト化してプログラムにパイプすることができます。
コンソールから直接入力する:
# ./prog1
Enter input: Stuff1
Your input: Stuff1
Enter input: Stuff2
Your input: Stuff2
Enter input: Stuff3
Your input: Stuff3
#
スクリプト入力:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1
Enter input: Your input: Stuff1
Enter input: Your input: Stuff2
Enter input: Your input: Stuff3
#
出力のフォーマットが少し乱れていますが、プログラムは期待どおりの出力を表示します。
私の問題は、2 番目のバイナリ prog2.c にあります。
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
read(0, buffer, 31);
printf("Your input: %s\n", buffer);
i++;
}
}
コンソールから直接入力できる場合:
# ./prog2
Stuff1
Enter input: Your input: Stuff1
Stuff2
Enter input: Your input: Stuff2
Stuff3
Enter input: Your input: Stuff3
#
入力を入力するまでプロンプトが表示されないだけでなく、入力をスクリプト化することさえできません。
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2
Enter input: Your input: Stuff1
Stuff2
Stuff3
Enter input: Your input:
Enter input: Your input:
#
fgets()
とread()
との違いについて調査を行い、次のことを発見しました。
fgets()
は C 関数read()
ですが、 はシステム コールです。fgets()
改行文字または EOF が検出されるまで入力を読み取りますが、改行はread()
syscallに対して同じ効果を持ちません。read()
ない何らかのバッファリングメカニズムを採用fgets()
しています。ポイント 2 と 3 は当面の問題に最も関連していると思いますが、問題を解決する方法を示唆していません。
これらのプログラムに与える必要のあるユーザー入力には、印刷できない 16 進バイトが含まれているため、コンソールからそのような入力を直接入力するだけでは不十分です。また、ソース コードをバイナリに変更することもできないため、fgets()
入力を収集するためだけに使用する回避策はありません。
私の質問は、prog2 に入力を供給して、prog1 と同じ動作をする方法があるかどうかです。
ありがとうございました。
この問題の回避策を見つけました。コンソールからの入力をスクリプト化するという、私が望む方法でバイナリを操作することはまだできませんが、プログラムでそれを行う方法を見つけました。
subprocess
モジュールのラッパーとして機能する Python ライブラリ スイートを使用していますが、独自に作成することもできます。
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
これにより、バイナリがプロセスとして開き、Python スクリプト内から send および receive 関数を使用してバイナリと対話できます。
これが、同様の問題に遭遇した他の人に役立つことを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加