背景:コマンドラインからコマンドを実行すると、コマンドで外部キーボードのCapsLockライトが点灯するようにしようとしています。理想的には、スクリプト化できるので、アラートなどに使用できます(キーボードを分解しました)。
私はそれが動作するはずのように見えるこのコマンドを手に入れました:
fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);
このコマンドをOSXまたは配置しているUbuntuサーバーのいずれかで実行しようとすると、次のようになります。
me@server1:~$ fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);
-bash: syntax error near unexpected token `('
me@server1:~$ fd=fdopen(/dev/console);
-bash: syntax error near unexpected token `('
したがって、問題は最初の部分にあるように見えます。ソフトウェア/ユーティリティのセットをインストールする必要がありますか?外部キーボードのCapsLockライトを手動で制御するにはどうすればよいですか?
あなたの問題は、Cコードをシェルプロンプトに入力しようとすることです。これは明らかな理由で機能しません。それを正しいCファイルに入れてコンパイルし、実行できる有効なバイナリを取得することができます。
#include <linux/kd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
static void
usage(char *argv0)
{
fprintf(stderr, "Usage: %s <on|off>\n", argv0);
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int fd;
int on;
unsigned char state;
if (argc != 2)
usage(argv[0]);
if (strcmp(argv[1], "on") == 0)
on = 1;
else if(strcmp(argv[1], "off") == 0)
on = 0;
else
usage(argv[0]);
fd = open("/dev/console", O_RDWR);
if (fd == -1)
err(EXIT_FAILURE, "open /dev/console");
if (ioctl(fd, KDGETLED, &state) == -1)
err(EXIT_FAILURE, "KDGETLED");
if (on)
state |= LED_CAP;
else
state &= ~LED_CAP;
if (ioctl(fd, KDSETLED, state) == -1)
err(EXIT_FAILURE, "KDSETLED");
close(fd);
return 0;
}
これをたとえばというファイルに入れます。 caps.c
そしてそれをコンパイルします:
$ gcc -o caps caps.c
次に、次のように実行できます
$ ./caps on
lEDをオンにするまたは
$ ./caps off
オフにします(切り替えは読者の練習問題として残されています)。
注:開くには/dev/console
スーパーユーザー権限が必要です。
さらに別の注意:これにより、端末またはXサーバーがCapsLock LEDをときどき変更することも妨げられません(例: Caps が押されます)。これはOSXでも機能しませんが、これを行うための標準化された方法がないため、Linuxでのみ機能します。最後に、複数のキーボードのLEDを個別に変更することはできません。
そのCコードはとにかく機能しません--fdopen()
は複数の引数を必要とし、ファイル記述子ではなくファイルストリームを返します。
数年前にこれを行ったことを覚えています。Xlib経由で考えましたが、古いコードが見つかりませんでした(コレクションが削除されることがあります)が、誰かがgithubなどでこれを行うための簡単なアプリを持っている必要があると思いました。低くて見よ、私が最初に見つけたページは これ 投稿した記憶はないが、4年前に私が書いたものだった(「akashiraffee」は私がオンラインでよく使った名前だった時間)。
実際にはXlibを使用していません-あなたがやろうとしていたようにioctl()
を使用しているので、GUIなしで動作するはずです。私はそれを片付けて、5LEDキーボードでここで試しました:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
int main (void) {
int tty = open("/dev/console", 0), led;
unsigned long int arg;
if (tty < 3) {
perror("open: ");
return -1;
}
if (ioctl(tty,KDGKBTYPE, &arg) > 0) perror("ioctl: ");
if (arg == KB_101) puts("You have a 101 key keyboard.");
for (led = 1; led < 9; led++) {
if (ioctl(tty,KDSETLED, led) > 0) perror("ioctl led on: ");
printf("LED %d on...hit enter", led);
getchar();
if (ioctl(tty,KDSETLED, led+0xff) > 0) perror("ioctl led off: ");
printf("off (hit enter)\n");
getchar();
}
close(tty);
return 0;
}
gcc whatever.c -o testleds
をコンパイルしてから./testleds
をコンパイルします(スーパーユーザー特権が必要です)。最初の7つは私のために働いた。それらのいくつかは個別のLEDであり、それらのいくつかは組み合わせです。
キーボードを分解しました
もちろん、それをテストするにはENTERが必要です。そうでない場合は、コメントを残してください。代わりに、遅延を使用して自動的にテストするように変更します。最終的に機能する場合は、番号でライトを切り替えるために使用できるものに変えていただければ幸いです(例:toggleLED 3
)。
あなたが投稿したのはCコードのスニペットです。 (そして、機能するものでさえありません。)それはシェルプロンプトでは機能しません。
ioctl
へのシェルインターフェースはありませんが、Perlを使用できます。
#!/usr/bin/Perl
require "sys/ioctl.ph";
if (@ARGV) {
$ioctl = 0x4b32; # KDSETLED
$ARGV[0] =~ /^[0-8]+$/ or die "$0: $ARGV[0]: invalid argument";
$arg = int($ARGV[0]);
} else {
$ioctl = 0x4b31; # KDGETLED
$arg = "?";
}
sysopen CONSOLE, "/dev/console", "r" or die "$0: /dev/console: $!\n";
ioctl CONSOLE, $ioctl, $arg or die "$0: ioctl: $!\n";
print ord($arg), "\n" unless @ARGV;
またはPython:
#!/usr/bin/env python
import array, fcntl, os, sys
console = open("/dev/console", "r")
if len(sys.argv) > 1:
fcntl.ioctl(console, 0x4b32, int(sys.argv[1])) # KDSETLED
else:
arg = array.array('B', [0xff]) # KDGETLED
fcntl.ioctl(console, 0x4b31, arg, True)
print arg[0]
どちらのプログラムも、引数なしで実行された場合は現在のLED設定を出力し、引数が渡された場合はLEDを変更します。 LED設定は、Scroll Lockの場合は1、Num Lockの場合は2、CapsLockの場合は4の合計として表されます。引数8を渡すと、OSのロック設定に対応するようにLEDをリセットできます。
独自のプログラムを呼び出す代わりに、標準の コンソールツール から setleds
ユーティリティを呼び出すこともできます。
テキストモードコンソール(Xの下でもリモートでもない)にログオンするか、rootとして実行する必要があります。
コンソールデバイスの代わりにそのデバイスにアクセスすることにより、特定の入力デバイスのLEDをオンまたはオフにすることもできます。 ioctlは異なります。 evdevインターフェース を使用して EV_LED
イベント 。
このインターフェースを使用する最も簡単な方法は、 evdev
Pythonパッケージ(pip install evdev
)。
</dev/input/by-id/usb-_USB_Keyboard-event-kbd \
python -c 'import evdev; dev = evdev.InputDevice("/dev/stdin"); print dev.leds()'
その他の例については、 チュートリアル の「LED状態の取得と設定」を参照してください。
Mac OS Xでは、 HIDインターフェイス を介してキーボードのLEDにアクセスできます。例と説明を見つけることができます Mac OS X Internals または サイキック折り紙 。