루프 변수가 작동을 멈췄습니다.

루프 변수가 작동을 멈췄습니다.

외부 USB 키보드가 연결되면 다른 레이아웃을 할당하는 작업 쉘 스크립트가 있지만 더 이상 작동하지 않습니다. sh에서 zsh로 전환했기 때문인지 모르겠습니다.

usbkbd_id="$(xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | grep "keyboard" | cut -c 1-2)"
for ID in $usbkbd_id; do
    setxkbmap -device ${ID} -layout "es"
done

명령으로 확인해 보니 echo "device: ${ID} layout: ${usbkbd_layout}" >> test.txt실제로 각 ID를 반복하지 않고 전체 첫 번째 변수 출력의 시작 부분에 "device:"만 추가한 것으로 나타났습니다.

비슷한 질문과 답변을 겪었고, ${usbkbd_id[@]}초급 수준의 스크립팅 기술을 사용하여 본 다른 대안을 시도했지만 이를 파악할 수 없습니다.

실제로 문제의 실제 원인은 외부 USB 키보드에 대해 항상 3개의 ID를 가져오고 실제로 그 중 하나만 키보드 레이아웃을 할당하는 데 작동하지만 어느 것인지 알 수 없다는 것입니다. 따라서 이 명령은 작동할 때도 있고 작동하지 않을 때도 있습니다(올바른 ID가 마지막 ID가 아닌 경우).

답변1

var=value스칼라 할당입니다. 그것은 할당한다하나값이 하나만 있습니다 $var. sh스칼라 할당이라는 동작 때문에 혼란스러울 수도 있지만 sh목록/배열 변수가 없으므로 참조되지 않은 경우 변수 확장은 특수 분할+glob 작업을 거칩니다.전반적으로 버그와 보안 문제가 많습니다.rc, 또는 ) es를 포함한 대부분의 최신 쉘에서 수정되었습니다 .fishzsh

여기서는 여러 값을 저장하려고 하므로 스칼라 변수 대신 배열/목록 변수를 사용하려고 합니다.

에서는 zsh배열 변수 할당이 다음과 같은 방식으로 수행됩니다.

var=( values )

통사론.

그래서:

usbkbd_ids=(
  $(xinput list | grep -Po 'USB Keyboard.*id=\K\d+(?=.*keyboard)')
)
for id in $usbkbd_ids; do
    setxkbmap -device $id -layout es
done

여기서는 다음과 같이 할 수도 있습니다.

xinput list |
  grep -Po 'USB Keyboard.*id=\K\d+(?=.*keyboard)' |
  xargs -I ID setxkbmap -device ID -layout es

awk을 사용할 필요가 거의 없으며 grep함께 cut사용하면 awk다른 두 명령의 상위 집합입니다. 그러나 awk패턴 기반 추출에는 그다지 좋지 않습니다(GNU awk확장을 사용할 수 없는 경우). 위의 내용 -P은 비표준 grep확장입니다. 표준 대안으로 다음을 사용할 수 있습니다 sed.

  xinput list |
    sed -n 's/^.*USB Keyboard.*id=\([0-9]*\).*keyboard.*/\1/p'

표준의 awk경우 다음과 같습니다.

xinput list |
  awk '/USB Keyboard.*id=.*keyboard/ && match($0, /id=[0-9]+/) {
         print substr($0, RSTART + 3, RLENGTH - 3)
       }'

zsh다음과 같은 고유한 패턴 추출 기능을 사용할 수도 있습니다 .

usbkbd_ids=()
for line (${(f)"$(xinput list)"})
  [[ $line =~ 'USB Keyboard.*id=([0-9]+).*keyboard' ]] &&
    usbkbd_ids+=$match[1]

관련 정보