如何存储变量并将变量从 ssh 会话传递到本地计算机

如何存储变量并将变量从 ssh 会话传递到本地计算机

我正在尝试在 ssh 会话中检索远程计算机上生成的 shell 变量。

echo -n "Enter the raspberry ip address you want to connect:"
read Rasp_id

sshpass -pthe@Donut ssh -oStrictHostKeyChecking=no pi@"$Rasp_id" << 'E7'
        #sudo rm -r SoundEye.zip
        mac_add=$(ip link show wlan0 | grep link | awk '{print $2}')
        timing=$(date)
E7

echo ${mac_add}
echo ${timing}

我尝试从 ssh 会话传递变量(在本例中是$mac_add和),它在本地计算机上。放在每个变量前面没有帮助。$timingecho/

echo /${mac_add}
echo /${timing}

在我想要声明的每个变量前面添加导出也是如此。它也不能解决问题。

答案1

假设在远程主机上执行的两个命令各产生一行输出:

{ read mac_addr; read timing; } < <(
sshpass -pthe@Donut ssh -o StrictHostKeyChecking=no "pi@$Rasp_id" <<'SSH_END'
    ip link show wlan0 | awk '/link/ { print $2 }'
    date
SSH_END
)

这会将远程命令生成的两行读入两个局部变量mac_addrtiming。数据read通过重定向进程替换传递到两个调用。

如果您假设date远程主机上的命令将输出与本地相同的内容,那么可以简化:

timing=$(date)
mac_addr=$(sshpass -pthe@Donut ssh -o StrictHostKeyChecking=no "pi@$Rasp_id" <<'SSH_END'
    ip link show wlan0 | awk '/link/ { print $2 }'
SSH_END
)

要不就

timing=$(date)
mac_addr=$(sshpass -pthe@Donut ssh -o StrictHostKeyChecking=no "pi@$Rasp_id" ip link show wlan0 | awk '/link/ { print $2 }' )

...awk在本地运行命令。


关于代码其余部分的简短说明:记住双引号任何变量扩展,并记住,如果您使用以下命令,readbash可以给用户提示-p

read -p 'Enter the raspberry IP address you want to connect: ' Rasp_id

还,为什么 printf 比 echo 更好?

答案2

由于您想要检索ssh会话中生成的输出,因此您可以尝试将会话的输出ssh总共存储在 shell 变量中,然后解析该输出以提取相关位。

以下应该有效。它将在相关行前面添加“开始标签”,以将它们与可能生成的其他消息(例如 motd)区分开来:

raw_output=$(sshpass -pthe@Donut ssh -oStrictHostKeyChecking=no pi@"$Rasp_id" 'echo "MAC=$(ip link show eth0 | awk '\''/^ *link/{print $2}'\'')"; echo "DATE=$(date)"')

mac_add=$(sed -E '/^MAC=/s/^[^=]+=//;t;d' <<< "$raw_output")
timing=$(sed -E '/^DATE=/s/^[^=]+=//;t;d' <<< "$raw_output")

然后通过调用提取相关值sed(通过搜索并用<tag>=“nothing”替换相关行开头的相应部分)并将其存储在脚本本地的 bash 变量中。

相关内容