С вашим пересмотренным вопросом, основанным на командной строке, а не на скрипте, самым простым решением будет использование подоболочки для выполнения вашей работы.
например
$ bash
$ x=100
$ echo $x
100
$ exit
$ echo $x
$
Все переменные, которые вы установили между запуском bash
и exit
этой оболочки, будут забыты.
Это очень похоже на то, как работает часть wget... | bash
, за исключением того, что вы можете вырезать и вставлять/печатать команды.
var=value
— скалярное присвоение. Он присваивает одно и только одно значение $var
. Возможно, вас смутило поведение sh
, где это также скалярное присваивание, но, поскольку sh
не имеет переменных списка/массива, расширение переменных, когда они не заключены в кавычки, подвергается специальной операции split+glob (причина из множество ошибок и проблем с безопасностью в целом и исправлены в большинстве более современных оболочек, включая rc
, es
, fish
илиzsh
).
Здесь, поскольку вы хотите сохранить несколько значений, вы хотите использовать переменную массива/списка, а не скалярную переменную.
В 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]