USB 키보드에 다른 키보드 레이아웃을 영구적으로 할당하는 방법은 무엇입니까?


16

나는 종종 랩톱에 USB 키보드를 플러그인하고 (외부 모니터와 마우스는 물론 랩톱을 데스크탑 컴퓨터로 거의 변환한다) 다른 키보드 레이아웃을 선호한다.

이 USB 키보드를 플러그인 할 때마다 현재 키보드 레이아웃을 수동으로 변경해야합니다.

가능한 경우 자동화 된 방법을 사용하고 싶습니다.

여기 질문에 대한 Radu 의 대답 은 실마리를 제공하지만 컴퓨터를 시작할 때마다 USB 키보드의 장치 ID가 변경 되므로이 작업에 대한 시작 스크립트 가 필요한 것 같습니다 .

이 시작 스크립트에는 먼저 명령 xinput -list | grep "USB Keyboard"과 표시되는 첫 번째 USB 키보드 ID 번호를 가져온 다음 마지막 명령 에서이 명령을 사용하여 다음과 같이 해당 USB 키보드에 대해 선택한 레이아웃을 설정하는 명령이 포함됩니다.

setxkbmap -device <NUMBER> -layout <LAYOUT>



1
@Sadi Martin Luther King 박사의 암살에 따라 Rutgers와 US 깃발을 거꾸로 뒤집는 것을 언급하고 있습니까? Paul Robeson : 182 페이지의 Freedomways 의 위대한 선구자
guest271314

고마워요! 그러나 나는 당신 이이 질문에 대해 어떻게 여기에 오게되었는지 궁금합니다. history.stackexchange.com/questions/48704/… ;-) 이것은 또 다른 현명한 항의 형식이지만 이것이 결국에는 내가 들었던 이야기 이야기.
Sadi

@Sadi 귀하의 질문은 정치에서 삭제되었습니다.
guest271314

답변:


15

약간의 연구를 한 후에도 여전히 다른 (아마도 더 나은) 답변에 열려 있지만 해결책을 찾았습니다.

여기의 시작 스크립트 (에 추가 할 수있는 시작 응용 프로그램 설정되는)는 maually 입력 usbkbd_layout 받는 변수 usbkbd 장치 ID 에서의 FOUND XInput에의 -list :

#!/bin/bash
usbkbd=`xinput -list | grep -c "USB Keyboard"`
if [[ "$usbkbd" -gt 0 ]]
then
    usbkbd_ids=`xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2`
    usbkbd_layout="tr(f)"
    for ID in $usbkbd_ids
    do
      setxkbmap -device "${ID}" -layout "${usbkbd_layout}"
    done
fi
exit 0

이 스크립트는 사용자가 데스크톱 설정 (노트북, 마우스 및 모니터 등)에서 랩톱을 사용하기 시작하고 외부 USB 키보드가 연결될 때마다 수동으로 실행할 수있는 시나리오에 매우 유용하고 안정적입니다. ...

===================================================== =========================

더 나은 (거의 완벽한) 솔루션 -MinimusHeximus 와 아래의 의견에서 언급 한 스레드에 대한 각 기여자 덕분에 발견되었습니다 .

이제 USB 키보드를 플러그인하면 노트북에 기본 키보드 레이아웃 (TR-Q)을 유지하면서 다른 (TR-F) 키보드 레이아웃을 자동으로 적용 할 수 있습니다!

이를 가능하게하는 파일과 내용은 다음과 같습니다.

/etc/udev/rules.d/00-usb-keyboard.rules

ATTRS{idVendor}=="09da", ATTRS{idProduct}=="0260", OWNER="sadi"
ACTION=="add", RUN+="/home/sadi/.bin/usb-keyboard-in_udev"
ACTION=="remove", RUN+="/home/sadi/.bin/usb-keyboard-out_udev"

/home/sadi/.bin/usb-keyboard-in_udev

#!/bin/bash
/home/sadi/.bin/usb-keyboard-in &

/home/sadi/.bin/usb-keyboard-in

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/sadi/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
usbkbd_id=`xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2 | head -1`
usbkbd_layout="tr(f)"
if [ "${usbkbd_id}" ]; then
    gsettings set org.gnome.settings-daemon.plugins.keyboard active false
    sleep 2
    setxkbmap -device "${usbkbd_id}" -layout "${usbkbd_layout}"
fi

/home/sadi/.bin/usb-keyboard-out_udev

#!/bin/bash
/home/sadi/.bin/usb-keyboard-out &

/home/sadi/.bin/usb-keyboard-out

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/sadi/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
gsettings set org.gnome.settings-daemon.plugins.keyboard active true

노트:

  1. 물론. "bin"폴더에있는 4 개의 파일 모두에 필요한 권한 (판독 가능 및 실행 가능)이 있어야합니다. chmod - 755 /home/sadi/.bin/usb-keyboard-*
  2. 때로는 USB 키보드를 꽂은 후에도 여전히 동일한 (기본) 키보드 레이아웃을 사용하고 두 번째 시도에서 지정된 레이아웃으로 전환합니다 (어딘가에 더 많은 수면 시간이 필요할까요?)
  3. USB 키보드 특정 레이아웃은 로그인 화면에서 유효하지 않습니다 (로그 아웃 할 때).
  4. 당신이에 대해 별도의 파티션을 사용하는 경우 / 가정 , 루트 파티션 어딘가, 예를 들어, 네 개의 스크립트를 넣어 더 좋은 생각이 될 수도 있습니다 / usr / 지방 / 빈을 따라 때로는 udev에가 볼 수있는 모든 각각의 파일의 내용을 수정 / home 파티션이 마운트 되기 전에 해당 파일 이 문제를 일으 킵니다.

이 요구 사항을 다른 요구 사항에 맞게 조정하려면 :

  1. 명령의 출력에 따라 USB 키보드 공급 업체 및 제품 ID를 변경해야합니다 lsusb(예 : 내 lsusb출력에 내 USB 키보드에 대한 출력이 있음 Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd).
  2. OWNER 및 모든 사용자 디렉토리 이름은 "sadi"에서 다른 이름으로 변경해야합니다.
  3. usbkbd_id 예를 들어, 명령의 출력 (정확한 기기 ID를 잡기 위해 약간의 조정이 필요할 수 xinput -list | grep "USB Keyboard"날 두 라인을 제공; ↳ USB Keyboard id=14 [slave keyboard (3)]↳ USB Keyboard id=16 [slave keyboard (3)] , 다음으로 필터링 awk필드 분리 "="를 사용하고, 두 번째 부분을 캡처 한 후 만 절삭을 처음 두 자리 숫자, 첫 번째 줄의 값만 사용)
  4. usbkbd_layout의 값은 다른 유효한 선택 일 수 있습니다.


2
이 지저분한 글타래에서 다른 답변을 게시 할 수 있다면 도움이 될 것입니다 : superuser.com/questions/249064/…
nano-merge me

1
@MinimusHeximus 감사합니다 백만 !!! 당신이 지적한 스레드를 겪고 시행 착오를 한 후에 마침내 그것을 분류 하고이 새로운 (거의) 완벽한 핫 플러그 ​​솔루션을 위에 추가 할 것입니다!
Sadi September

1
어떤 이유로 든 내 키보드에는 두 개의 ID가 있으므로을 사용하는 대신 IF을 사용해야했습니다 FOR. 그것은 나를 위해 지금 작동합니다, 감사합니다! gist.github.com/zvictor/193b567c14b5b6a679fe
zVictor

1
@Sadi 저는 평범한 사용자입니다. 내 솔루션을 여기에 게시합니다. 어쩌면 당신은 그것에 대해 몇 가지 아이디어를 취할 수 있습니다.
kleinfreund

9

udev 규칙 내에서 X11 드라이버 옵션을 지정할 수 있으며 사용자 정의 스크립트가 필요하지 않습니다. 예를 들어 다음은 /etc/udev/rules.d/99-usb-kbd.rules 의 내용입니다.

ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2323", ENV{XKBMODEL}="pc104", ENV{XKBLAYOUT}="us", ENV{XKBVARIANT}="euro", ENV{XKBOPTIONS}="compose:caps"

이 규칙은 Xorg에서 특정 USB 키보드가 미국 레이아웃을 사용하도록합니다 (노트북의 내부 키보드는 독일어이며 이것이 기본 레이아웃이기도합니다). 중요한 점 :

  1. 당신은 찾을 수 idVendoridProduct사용하여 장치의 lsusb또는evtest
  2. 의 모든 레이아웃을 사용할 수 있습니다 /usr/share/X11/xkb/symbols. 유효한 레이아웃과 유효한 변형을 모두 지정하도록주의하십시오.
  3. 설정이 시스템 전체 설정을 덮어 쓰려면 파일 이름이 64보다 큰 숫자로 시작해야합니다. /lib/udev/rules.d/64-xorg-xkb.rules
  4. Gnome / KDE 레이아웃 관리가 설정을 덮어 쓰지 않도록하십시오.

키보드를 분리했다가 다시 연결 /var/log/Xorg.0.log하고 가능한 문제 가 있는지 확인하십시오. udevadm info설정이 올바르게 적용되었는지 확인할 수도 있습니다 .
pavel

유레카! 현재 gconf 설정을 무시하기 위해이 명령을 한 번 입력 한 후에 만 ​​스마트 솔루션이 작동하기 시작했습니다 gsettings set org.gnome.settings-daemon.plugins.keyboard active false. 당신은 또한 메모를 추가 할 경우, 나는 같이 당신을 표시하려고합니다 ;-) 길고 구불 구불, 답 (대신의 서투른
사디

이것은 예외적입니다. Ubuntu 14.04에서 가능한 모델 / 레이아웃 / 옵션 / 등. /usr/share/X11/xkb/rules/evdev.lst
Jon

2
불행히도이 훌륭하고 쉬운 솔루션 은 Ubuntu Gnome 17.04로 업그레이드 한 후 작동 하지 않습니다. :-(
Sadi

우분투 16.04 LTS를 기반으로 리눅스 민트 18.2을, 시도 udev에 버전 229-4ubuntu19 , 다시 아무 효과 없음 :-( ???이 이상한 udev에 동작에 대한 어떤 아이디어
사디

2

방금 bépo Typematrix 키보드 (최적의 우수한 dvorak의 프랑스어 버전) 및 넓은 시스템 컨텍스트 (이 시스템에 루트 액세스 권한이 있다고 가정)에 대해이 솔루션을 개선했습니다. 3 개의 파일 만 있으면 작동합니다. 실패한 것을 파악하지 못한 경우 로그 파일을 참조 할 수 있습니다.

/etc/udev/96-usb-keyboard.rules

ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/etc/udev/bepo-typematrix-kbd.sh in"
ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/etc/udev/bepo-typematrix-kbd.sh out"

/etc/udev/bepo-typematrix-kbd.sh (중간 백그라운드 스크립트를 사용하려면 반드시 필요)

#!/bin/bash

dir=$(dirname $0)
command=$(basename $0)
command=$dir/${command%\.sh}
arg=$1 # must be "in" or "out"
LOG=/var/log/bepo-typematrix-kbd.log

[ -x "$command" ] && $command $arg >$LOG 2>&1 &

/ etc / udev / bepo-typematrix-kbd

#!/bin/bash
# jp dot ayanides at free.fr

MODEL="tm2030USB-102" # keyboard model
DISPLAY=':0.0'
GSETTING=/usr/bin/gsettings
XSET=/usr/bin/xset
SETXKBMAP=/usr/bin/setxkbmap
XINPUT=/usr/bin/xinput

USER=$(/usr/bin/who | /usr/bin/awk -v DIS=':0' '{if ($2==DIS) print $1}')
eval HOME=~$USER
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME

case $1 in
        'in')
                BEPO=$($XINPUT list --short | grep "TypeMatrix.com USB Keyboard" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*/\1/g')
                if [ -n "$BEPO" ]; then
                        [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active false
                        # apparently nothing to do with TDE (trinity KDE)
                        for ID in $BEPO; do # case of multiple bepo keyboard is taken into account
                                [ -x $SETXKBMAP ] && $SETXKBMAP -device $ID -model $MODEL -layout fr -variant bepo
                        done
                fi
                echo "bépo keyboard id(s) is (are) $BEPO"
                [ -x $XSET ] && $XSET -display $DISPLAY r rate 250 40
        ;;
        'out')
                # apparently nothing to do with TDE (trinity KDE)
                [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active true
        ;;
        *)
                printf "wrong parameter: $1\n"
                exit 1
        ;;
esac

1

많은 것을 둘러 본 후에, 이것은 내가 지금 달리고있는 것입니다. 아마도 완전한 종류의 기사를 작성하고 관심있는 저장소에 코드를 게시 할 것입니다.


다음과 같이 udev에 대한 새 규칙 세트를 설정하십시오.

 sudo gedit /etc/udev/rules.d/80-external-keyboard.rules

벤더와 제품 ID의 주어진 조합을 가진 장치에 의해 어떤 동작이 트리거 될 때마다 규칙은 쉘 스크립트를 호출해야합니다.

ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="4042", RUN+="/home/phil/.bin/switch-kb-layout-wrapper.sh"

새 규칙 세트를 추가 한 후 udev 서비스를 다시 시작하십시오.

sudo service udev restart

참고 : 해당 파일에서보다 구체적인 일치 규칙을 제공하여 안정적인 결과를 얻을 수 없었습니다. 가장 중요한 것은 ACTION일치 규칙을 추가 해도 작동하지 않습니다. 내가 알 수있는 한, 스크립트는 어쨌든 트리거되었습니다. 를 추가 할 때 ACTION=="add"장치를 제거해도 스크립트가 계속 호출됩니다. 매우 이상하고 혼란 스럽다.

그러나 udev 규칙을 트리거 한 조치는 다음과 같이 호출 된 스크립트에서 사용할 수 있습니다.


다음으로 스크립트 자체입니다. 글쎄요 노트 wrapper파일 이름에 접미사. 이것은 이것이 실제 스크립트가 아니라 스크립트를 호출하고 백그라운드에서 스크립트를 실행하여 udev가 프로세스를 완료 할 수있는 랩퍼임을 나타냅니다.

~/.bin/switch-kb-layout-wrapper.sh:

#!/bin/sh
/home/phil/.bin/switch-kb-layout.sh "${ACTION}" &

변수 ACTION는 장치에 의해 트리거 된 udev 조치를 포함합니다. add(장치가 연결됨) 및 remove(장치가 제거됨) 과 같은 값을 생성합니다 . 우리는 나중에 이것을 사용할 것입니다.

~/.bin/switch-kb-layout.sh:

#!/bin/sh

sleep 1

# Some environment variables that need to be set in order to run `setxkbmap`
DISPLAY=":0.0"
HOME=/home/phil
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME

udev_action=$1
log_file="$HOME/switch-kb-layout.log"

if [ "${udev_action}" != "add" ] && [ "${udev_action}" != "remove" ]; then
    echo "Other action. Aborting." >> $log_file
    exit 1
fi

internal_kb_layout="de"
internal_kb_variant=""

external_kb_layout="us"
external_kb_variant="altgr-intl"

kb_layout=""
kb_variant=""

if [ "${udev_action}" = "add" ]; then
    kb_layout=$external_kb_layout
    kb_variant=$external_kb_variant
elif [ "${udev_action}" = "remove" ]; then
    kb_layout=$internal_kb_layout
    kb_variant=$internal_kb_variant
fi

setxkbmap -layout "${kb_layout}"
echo "set layout:" "$kb_layout" >> $log_file
if [ ! -z "${kb_variant}" ]; then
    setxkbmap -variant "${kb_variant}"
    echo "set variant:" "$kb_variant" >> $log_file
fi

HOME변수를 설정할 때 내 사용자 이름을 사용자 이름으로 바꾸십시오 ( $(whoami)여기서는 사용자가 아니라 호출하기 때문에 작동하지 않습니다 root).

sed -i "s/phil/YOUR_USERNAME/g" ~/.bin/switch-kb-layout.sh

테스트 목적으로 홈 디렉토리의 파일에 특정 이벤트를 기록하는 행을 추가하여 모든 것이 작동하는지 확인했습니다. 당신은 이것을 안전하게 제거 할 수 있습니다.


마지막으로 이러한 스크립트에는 실행 권한이 있어야합니다. 또한이 스크립트는 root사용자 가 호출 하므로주의해야합니다.

chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh 

1
고마워, 대단해! 나는 그것을 작동시켰다. 그러나 플러그인을 사용할 때 14 번의 "조치 추가"와 3 번의 "기타 조치"가 표시되는 이유는 외부 명령이 미스터리이므로 나중에 해결하려고합니다. 그러나 최신 자동 시작 스크립트에서와 같이 내부 키보드와 외부 키보드를 계속 사용할 수 있도록 setxkbmap 명령에 장치 ID를 추가하는 것이 좋습니다. 나는이에게 며칠을위한 시도를주고, 여기에 약간의 수정과 함께 아마도, 다시 와서 당신이 답으로 간주 될 수 있는지 거기 ;-)거야
사디

또한 동일한 로그 라인을 여러 번 가져옵니다. 명령에서 장치 ID를 잘 잡습니다.
kleinfreund

@Sadi 또한 gsettings set org.gnome.settings-daemon.plugins.keyboard active false스크립트가에 의해 실행 되므로 라인 이 의도 한대로 작동하지 않는다고 생각합니다 root. 내 테스트에서 라인은 해당 설정에 영향을 미치지 않았습니다.
kleinfreund

이러한 시나리오에서는 gsettings set org.gnome.settings-daemon.plugins.keyboard active false사용자로서 명령 을 한 번 에 실행 한 다음 gsettings set명령 없이이 스크립트를 사용 하는 것이 좋습니다 .
Sadi

지금까지 나는이 일이 순조롭게 진행될 수 없다는 것을 알았다. 때때로 키보드 레이아웃은 udev에 의해 구현되지 않으며, 플러그를 꽂았다가 다시 연결해야합니다. 나는 대답의 맨 위에있는 (업데이트 된) 시작 스크립트로 다시 돌아가서 더 원활하게 작동한다고 생각합니다. 시작 후 외부 키보드를 연결하면 수동으로 실행해야합니다. udev는 너무 많은 액션 반복에서 볼 수 있듯이 약간 버그가있는 것 같습니다 (래퍼 스크립트를 여러 번 실행하고 이상한 방식으로 실행) ...
Sadi

1

udev가 실행 한 스크립트에 권한 문제가 있습니다. 다음과 같이 sudo로 해결했습니다.

# Estract id of MX3 keyboard devices that present themself as "123 COM Smart Control"
    IDLIST=$(sudo -u max /usr/bin/xinput -list | grep "123 COM Smart Control" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*/\1/g')

각 장치에 대한 키보드 맵을 설정하십시오

    for ID in $IDLIST; do
            sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0
    done

나는 당신이 그것을 완전히 쓸 수 있다면 더 유용 할 수 있다고 생각합니다. 예를 들어, 위의 라인을 어디에 놓았습니까?
Sadi

0

Xorg 설정 파일에서 정의 할 수도 있습니다.

이 스택 교환 답변에 설명되어 있습니다. /superuser//a/946575/437492


내가 그것을 얻을 수 있다면 그것은 좋을 것입니다. 그러나 최신 LTS 릴리스 인 Ubuntu 18.04를 사용하면 40-libinput.conf 라는 파일이 포함 된 /usr/share/X11/xorg.conf.d/ 디렉토리 만 볼 수 있습니다 . 따라서 해당 파일에 외부 키보드에 대한 섹션을 추가했습니다. 드라이버 libinput 또는 evdev 와 더 길고 짧은 공급 업체 이름을 사용하여 결과를 얻을 수 없었습니다. 어떤 아이디어?
Sadi

@Sadi : Xorg 설정에 대해 조금 읽어 보면 새 파일을 추가 할 수 있다는 것을 알게 될 /etc/X11/xorg.conf.d/것입니다.
Golar Ramblar

감사. 필자는 꽤 많이 읽고 먼저 "/etc/X11/xorg.conf.d/30-keyboard.conf"를 사용해 보았습니다. 위에서 언급 한 stackexchange 답변에서 운을 시험해 보겠습니다. ;-)
Sadi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.