如何存储来自 CLI 工具的值以便稍后在同一个 bash 脚本中使用?

How to storing values from a CLI tool to use in later in the same bash script?

你好惊人的堆栈溢出人,

在我的 bash 脚本中使用 CLI 工具时,我一直坚持存储 returned 的值,我的目标是自动执行一些我必须 运行 的命令每次我为客户设置新设备时。我几乎必须对每个产品执行 this,并且想创建一个脚本来自动执行该例程。

#!/bin/bash
particle usb start-listening

RESULT=$(particle serial identify $OUTPUT) 
if [ $? -eq 0 ]; then
    printf '%s\n' "$RESULT"
else
    printf '%s\n' "No Match"
fi

这个 return 发送到终端的这个文本

Your device id is e00fce681fffffffffc08949b
Your IMEI is 352999999084606
Your ICCID is 8901413111111117667
Your system firmware version is 1.5.0

我的目标是存储 device idICCID,然后在接下来的几个 particle-CLI 命令中使用。

喜欢这个激活sim卡的curl请求,

curl -X PUT https://api.particle.io/v1/sims/<$ICCID> \
       -d action=activate \
       -d access_token=<$ACCESS_TOKEN>

并将设备添加到我们的帐户进行测试

particle device add <device_id> 

我花了一个上午尝试不同的教程和命令来解析来自第一个命令的 return 数据并存储 devcie_ID 和 ICCID 无济于事。

我试过了awk:

read deviceId IMEI ICCID <<< $("particle serial identify" | awk '/is[[:space:]]/ { print  }')

我试过了IFS=' ':

IFS=' ' 
read -r first second third fourth fifth sixth seven eight night ten eleven twelve thirten fourten fiften sizten seventen <<< "$RESULT"
read -a strarr <<< "$RESULT"
for val in "${strarr[@]}";
do
  echo "$strarr\n"
done

我以前从未写过 bash 脚本,所以如果有任何帮助指向有关如何执行此操作的更好的文档,我很乐意阅读和学习。我只是觉得我还没有完全理解 bash 是如何处理字符串的,而且还没有找到任何解释发生了什么的文档。

我希望在 bash 脚本编写方面有更多经验的人可以为我指明正确的方向。

在某些时候,当我更想编写一个 Node 程序来处理制造过程中每个设备的设置和测试时,我也有兴趣学习如何创建一个 Go CLI 工具来将来管理我们的设备。

我什至不确定我想要完成的事情是否可以只用一个 bash 脚本来完成。

干杯, N

您可以将命令的输出保存到变量文件并解析必要的变量

file=$(particle serial identify $OUTPUT) 
device_id=$(echo $file| grep -Eo 'device id is .+?$' |sed 's/device id is //g')
ICCID=$(echo $file| grep -Eo 'ICCID is .+?$' |sed 's/ICCID is //g')
echo $device_id
echo $ICCID

首先,一些通用的脚本建议:使用小写或混合大小写的变量名是最安全的(例如 resultResult 而不是 RESULT),以避免与具有特殊含义或功能的各种全大写名称。 运行 您的脚本到 shellcheck.net,因为它擅长发现常见的脚本错误。如果您正在尝试调试脚本,请在问题部分之前添加命令 set -x 以获取正在发生的事情的执行跟踪(并在其后添加 set +x 以关闭跟踪)。

至于像这样从字符串中提取相关信息:有很多方法可以做到这一点,但都有点笨拙,使用哪一种主要是个人喜好问题。在这种情况下,我倾向于使用 sed 来提取相关位:

deviceID=$(sed -n 's/^[[:space:]]*Your device id is //p' <<<"$result")
iccid=$(sed -n 's/^[[:space:]]*Your ICCID is //p' <<<"$result")

解释:sed 通常传递所有输入(修改后),但 -n 告诉它不要传递任何东西(即“打印”它),除非明确告知。 s/^[[:space:]]*Your device id is //p 告诉它用空字符串替换一些 space 后跟“您的设备 id 是”,然后打印结果;因为这只留下设备 ID(并且“打印结果”只发生在替换发生的行),它只打印设备 ID。

你也可以用 awk:

deviceID=$(awk '/Your device id is / {print $NF}' <<<"$result")
iccid=$(awk '/Your ICCID is / {print $NF}' <<<"$result")

此处的 /Your device id is / 表示“在与该字符串匹配的行上”,{print $NF} 打印该行的最后一个(space 分隔)字段。

另一种方法是使用 bash 的内置变量修剪修饰符:

tempString=${result#*Your device id is }
deviceID=${tempString%%$'\n'*}
tempString=${result#*Your ICCID is }
iccid=${tempString%%$'\n'*}

这里,变量扩展的#*Your ICCID is 修饰符从字符串的开头(#)到(*)删除字符串“Your ICCID is”,然后%%$'\n'* 从末尾 (%%) 删除到换行符(双 %% 使其尽可能多地删除,即从 first,而不是 last,换行符)。有关这些(和其他)修饰符的更多信息,请参阅 here

顺便说一句,当你得到 RESULT 字符串时,你使用命令 particle serial identify $OUTPUT。什么是 $OUTPUT?该变量似乎没有设置任何值,因此(因为它没有被双引号引起来)它会从命令中消失。是故意的吗?