키를 누르는 데 사용 된 키보드를 확인하는 방법?


16

여러 키보드가 설치된 페어링 스테이션에서 자주 작업합니다. setxkbmap와 함께 사용 -device <ID>하여 특정 키보드의 레이아웃을 설정할 수 있지만 (의 IDxinput 사용 ) 종종 어떤 키보드를 사용하고 있는지 명확하지 않습니다. 두 키보드를 모두 시도하는 것을 피하는 것이 좋습니다. 따라서이 정보를 얻을 수있는 빠른 도구를 작성하고 싶습니다 setxkbmap. 다음과 같은 일반적인 유스 케이스를 기대합니다.

$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID

Linux에서이 정보를 제공하는 인터페이스는 무엇입니까? 이상적으로는 X없이 작동해야하지만 요구 사항은 아닙니다 (X없이 이것을 지원하는 많은 도구는 보이지 않습니다).


지금까지의 결과 :

  • Linux 여러 키보드에 대해 서로 다른 레이아웃을 동시에 지원하기 위해 입력하는 키보드 알고 있어야합니다 .
  • xinput→ list.c → list_xi2→에서 XIQueryDevice사용할 수있는 장치 ID를 제공합니다 setxkbmap.
  • showkeyxev키보드 ID를 인쇄되지 않습니다.
  • xinput list-props $ID키보드 이벤트가 전송되는 위치를 보여줍니다 . 그러나 다른 답변의 코드를 사용 하면이 장치가 키보드를 식별하기 위해 아무것도 인쇄하지 않는 것 같습니다.
  • 거의 가능한 해결책 중 하나는 xinput --test <ID> &각 키보드 ID마다 실행 하고 어떤 것이 먼저 무언가를 반환하는지 확인하는 것입니다. 이것의 문제점은 어떤 "키보드"가 실제로 키보드 인지 알아내는 것입니다 .

    $ xinput | grep keyboard
    ⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
        ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
        ↳ Power Button                              id=6    [slave  keyboard (3)]
        ↳ Video Bus                                 id=7    [slave  keyboard (3)]
        ↳ Power Button                              id=8    [slave  keyboard (3)]
        ↳ Sleep Button                              id=9    [slave  keyboard (3)]
        ↳ WebCam SC-13HDL10931N                     id=10   [slave  keyboard (3)]
        ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    

1
아마도 당신은 MPX를 찾고있을 것입니다.
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams 그렇게 복잡한 솔루션이 아닌가?
l0b0

그것은 문제가 무엇인지에 달려 있습니다.
Ignacio Vazquez-Abrams

"이 장치는 키보드를 식별하기 위해 아무것도 인쇄하지 않는 것 같습니다."무슨 의미입니까? 당신이 경우 less -f /dev/input/eventX및 해당 키보드의 키를 누르면, 당신은 당신의 키 누름이 실제로 다른 사람을 하나 개의 디바이스 파일로 연출되지 않도록 "쓰레기", 게재 볼 수 있습니다.
L. Levrel

당신 이 이것을 시도 했습니까 (당신 인용 한 다른 질문에 대한 다른 대답에서 언급 되었습니까)?
L. Levrel

답변:


4

장치 비활성화

다음은 어떤 키보드가 어떤 키보드인지 식별하는 아이디어입니다. xinput 명령을 사용할 수 있습니다 을 사용하여 장치를 활성화 및 비활성화 할 수 있습니다.

$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=12   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     id=13   [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=9    [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=10   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                    id=14   [slave  keyboard (3)]

위 출력은 Thinkpad 랩탑에있는 다양한 장치를 보여줍니다. 하나의 키보드 만 연결되어 있습니다.

    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]

이제이 장치를 통해 사용할 수있는 속성을 살펴보십시오.

$ xinput list-props "AT Translated Set 2 keyboard"
Device 'AT Translated Set 2 keyboard':
    Device Enabled (124):   1
    Coordinate Transformation Matrix (126): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.

위로부터 활성화되어 있음을 알 수 있으므로 비활성화하십시오.

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 0

사용하려면 다음을 수행하십시오.

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 1

아이디어?

이 명령을 사용하여 키보드 중 하나를 비활성화하여 사용중인 키보드를 확인할 수 있습니다.

참고 문헌


더 많은 일이 아닌가? 내 접근 방식에는 최소한 하나의 명령, 최대 3 개가 포함됩니다. 이 방법에는 항상 세 가지 명령, 즉 비활성화, 활성화 및 레이아웃 설정 (및 키보드 스위치)이 포함됩니다.
l0b0

@ l0b0-그래, 나는이 접근법에도 흥분하지 않습니다. 나는 계속보고 있지만이 방법을 "1 가지 방법"으로 여기고 있습니다. 그러나 이상적인 것은 아니지만 동의합니다.
slm

@lobo-이 답변은 현상금을 얻지 않으므로 걱정하지 마십시오. 현상금을 시작하기 전에 투표했습니다. stackoverflow.com/help/bounty . 또한 당신을 도와 주려는 당신의 분노는 무엇입니까? 이상적인 솔루션은 아니지만 작업을 수행하는 한 가지 방법을 제공했습니다. 나는 2 년 이상 전에 이것을 제공 했으며이 Q는 0 대안으로 여기에 앉아있다. 나는 그것이 문제인 질문 / 접근인지 스스로에게 물어볼 필요가 있다고 생각합니다. 분명히 내 $ 0.02이지만 이미 충분합니다.
slm

나의 나쁜 x 2 : 나는 "현상금이 시작된 후 만들어진"에 대해 조금도 눈치 채지 못했고, 당신이 매우 잘 정돈 된 답변을 썼음을 감사합니다. 그러나 원래 솔루션보다 복잡한 솔루션을 공표 할 수 없으며 다른 사람들이 왜 그런지 이해할 수 없습니다.
l0b0

1
@ l0b0 업 보팅에 대한 나의 이유 : 하드 드라이브를 지우지 않도록 전체 스크립트를 읽은 다음 저장하고 그것을 실행하십시오. 또는 지금까지 가장 높은 투표 응답의 경우 C 코드를 컴파일하십시오. 또한 이와 같은 창의적인 아이디어는 공감할 가치가 있습니다.
Fabian Röling

4

X 툴을 인용하고 있지만 "이상적으로 X없이 작동해야한다"는 솔루션을 요구하기 때문에이 질문은 약간 모순된다.

번째 발견에 관하여 : xinput당신에게 서신을 줄 것입니다

$ xinput list-props 11
Device 'AT Translated Set 2 keyboard':
    Device Enabled (145):   1
    Coordinate Transformation Matrix (147): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Product ID (266):    1, 1
    Device Node (267):  "/dev/input/event0"

적어도 다음 버전에서는

$ xinput --version
xinput version 1.6.1
XI version on server: 2.3


첫 번째 단계 : C에서 키보드 이벤트 장치 감지

#include <stdio.h>
//#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

// typical use : sudo ./a.out /dev/input/event*
int main (int argc, char *argv[])
{
  struct input_event ev[64];
  int fd[argc],rd,idev,value, size = sizeof (struct input_event);
  char name[256] = "Unknown";

  if(argc==1) return -1;

  int ndev=1;
  while(ndev<argc && (fd[ndev] = open (argv[ndev], O_RDONLY|O_NONBLOCK)) != -1){
    ndev++;
  }
  fprintf (stderr,"Found %i devices.\n", ndev);
  if(ndev==1) return -1;

  while (1){
    for(idev=1; idev<argc; idev++){
      if( (rd=read (fd[idev], ev, size * 64)) >= size){
      value = ev[0].value;
      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){
        ioctl (fd[idev], EVIOCGNAME (sizeof (name)), name);
        printf ("%s\n", name);
        return idev;
      }
      }
    }
//    sleep(1);
  }
  return -1;
}

이 페이지 덕분에 많은 감사 . 필자는 여기서 빌린 코드에서 대부분의 안전 점검을 명확하게하기 위해 실제 코드에서 아마도 원하는 것을 제거했습니다.

키 누름은 에코되므로 실제로 사용자에게 수정 자 키 (Shift, Control ...)를 누르지 말라고 친절하게 요청할 수 있습니다. 키를 누릅니다.

두 번째 단계 : xinput을 사용하여 장치 이름에서 X ID를 가져옵니다.

위의 C 소스를 컴파일하고 다음과 같이 사용하십시오.

xinput list --id-only "keyboard:$(sudo ./a.out /dev/input/event*)"


또한/dev/input/by-id
jthill

팁 고마워. 대부분의 도구 내가 할 X를 필요로하는 것 때문에 만 나는 X 도구를 인용 한 하지 작업하는 방법을 알고 /dev/input/event*내가 시도 - tail하지만 아무 소용 팅을.
l0b0

by-id는 X를 요구하지 않고 장치 이름을 이벤트 대기열에 매핑하는 심볼릭 링크를 제공합니다.
jthill

@jthill 현재 켜져있는 컴퓨터에서이 디렉토리에는 마우스 링크 만 있습니다.
L. Levrel

훈 좋아, 살고 배우고 내 키보드는 모두 예쁘게 나열되어 있습니다.
jthill

1

더 많은 파기 작업은 일반 Bash와 일반 사용자 계정을 사용하는 다른 솔루션 을 공개했습니다 . 스크립트 :

#!/usr/bin/env bash

set -o errexit -o nounset -o noclobber -o pipefail

# Remove leftover files and processes on exit
trap 'rm --recursive -- "$dir"; kill -- -$$' EXIT
dir="$(mktemp --directory)"
cd "$dir"

# Log key presses to file
xinput --list --id-only | while read id
do
    # Only check devices linked to an event source
    if xinput --list-props "$id" | grep --quiet --extended-regexp '^\s+Device Node.*/dev/input/event'
    then
        xinput test "$id" > "$id" &
    fi
done

# Check for key presses
while sleep 0.1
do
    for file in *
    do
        if [[ -s "$file" ]]
        then
            echo "$file"
            exit
        fi
    done
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.