0

我编写了一个带有 while 循环的脚本,但没有意识到从所述 while 循环中获取变量的难度。

我想要做的是在while循环完成所需的循环数之后运行while循环保存在'stream'变量中的命令(参见下面的代码)。我正在使用这个脚本来检测连接了哪些游戏控制器并创建了一个初始化月光的命令,这是一个用于覆盆子 pi 的程序,它允许我使用不同的控制器类型通过 Nvidia Game Stream 进行流式传输。

#!/bin/bash

stream="moonlight stream -1080 -app Steam"
device=none

event=0

Player="-input /dev/input/event"

XbElite="-mapping /opt/retropie/configs/moonlight/XboxOne.map"
PlSt3="-mapping /opt/retropie/configs/moonlight/PS3.map"

XboxElite="N\:\ Name\=\"Microsoft\ X\-Box\ One\ Elite\ pad\""
PS3="N\:\ Name\=\"PLAYSTATION\(R\)3\ Controller\""

cat /proc/bus/input/devices | \
while read CMD; do
    line=$(echo "$CMD" | sed 's/ /\\ /g; s/:/\\:/g; s/(/\\(/g; s/)/\\)/g; s/-/\\-/g; s/=/\\=/g')
    if [ "$line" = "$XboxElite" ]; then
        echo Xbox
        device=xboxElite
        if [ "$device" = "xboxElite" ]; then
            stream="$stream $XbElite $Player$event"
            event=$((event+1))
            device=none
        fi
    elif [ "$line" = "$PS3" ]; then
        echo PS3
        device=ps3
        if [ "$device" = "ps3" ]; then
            stream="$stream $PlSt3 $Player$event"
            event=$((event+1))
            device=none
        fi
    fi
done
echo $stream #put here as a placeholder to see the final command in the variable. Currently printing: 'moonlight stream -1080 -app Steam'

我意识到这可能不是最干净的方式,或者代码甚至接近尽可能好,但由于我以前没有任何类型的编码经验,这就是我可以管理的暂且。

任何帮助将不胜感激!

4

2 回答 2

1

好吧,将它作为命令运行的方法就是删除echo

done
$stream

...除了你不能,因为while循环在管道的右侧。这意味着它在“子外壳”中运行,并且不能在其父外壳(循环外)中产生副作用;循环退出后,$stream将恢复到循环前的状态。

为了将循环保持在与周围代码相同的环境中,而不是它自己的子shell,您需要直接从文件中读取,而不是使用管道:

# no `cat` command here.  No pipe.
while read CMD; do
...
done </proc/bus/input/devices #this replaces the `cat |`.
$stream

在一般情况下,当动态构建命令以稍后运行时,您将遇到引用或空格或其他特殊字符的问题。如果您在数组而不是字符串中构建命令,则最容易避免这些问题。在数组中构建和运行命令的语法如下所示:

stream=(moonlight stream -1080 -app Steam)
...
while read CMD; do
  ...
  stream+=("$XbElite" "$Player$event")
  ...
  stream+=("$PlSt3" "$Player$event")
...
done </proc/bus/input/devices
"${stream[@]}"
于 2016-10-15T03:46:14.043 回答
0

Mark Reed所说的,主循环也可以简化:

sed 's/\([-:\( )=]\)/\\&/g' /proc/bus/input/devices | \
while read line; do
    if [ "$line" = "$XboxElite" ]; then
        echo Xbox
        stream="$stream $XbElite $Player$event"
        event=$((event+1))
    elif [ "$line" = "$PS3" ]; then
        echo PS3
        stream="$stream $PlSt3 $Player$event"
        event=$((event+1))
    fi
done 
于 2016-10-15T06:09:34.113 回答