Bash 脚本:变量值未在“单行”脚本中更新

Bash 脚本:变量值未在“单行”脚本中更新

在以下“一行代码”中,当我ID在脚本开头更改变量值时,disk后面的变量似乎没有更新。也就是说,在脚本的末尾,该>> /md0/DiskAnalysis/$disk.txt部分使用的变量值是由与脚本开头定义的变量值$disk不同的变量值生成的。$ID

完整的单行脚本

nohup sh -c ID="c"; disk=`udevadm info --query=all /dev/sd$ID | grep ID_SCSI_SERIAL | awk -F'=' '{print $2}'`; size=`lsblk -b --output SIZE -n -d /dev/sd$ID`; size=`echo "$size / 1024 / 1024 / 10" | bc`; for i in $(seq 0 $size); do dd if=/dev/sd$ID of=/dev/shm/$ID.dd bs=10M skip=$i count=1 2>1; sha256=`sha256sum /dev/shm/$ID.dd | awk -F' ' '{print $1}'`; md5=`md5sum /dev/shm/$ID.dd | awk -F' ' '{print $1}'`; echo "$i,$sha256,$md5" >> /md0/DiskAnalysis/$disk.txt; done &

因此,当我更改ID="b"ID="c"

disk=`udevadm info --query=all /dev/sd$ID | grep ID_SCSI_SERIAL | awk -F'=' '{print $2}'`

脚本的这一部分不会更新其值以反映变量值的变化$ID。但是,如果我在终端中单独执行以下操作:

ID="b"; disk=`udevadm info --query=all /dev/sd$ID | grep ID_SCSI_SERIAL | awk -F'=' '{print $2}'`; echo $disk

ID="c"; disk=`udevadm info --query=all /dev/sd$ID | grep ID_SCSI_SERIAL | awk -F'=' '{print $2}'`; echo $disk

我得到了两个不同的值$disk

我遗漏了什么导致$disk变量值在完整脚本中没有更新?

目前,我假设$ID脚本其他部分(即校验和)的值更改工作正常。但是,由于值$disk未正确更新,因此输出未写入所需文件。事实上,每次我使用与$ID原始值不同的值运行脚本时(ID="b"),脚本其余部分的输出都会简单地写入$disk由第一个原始值定义的输出文件(即 )$ID

谢谢。

答案1

那里没有引用,也没有转义;

nohup sh -c ID="c"; whatever先运行nohup sh -c ID="c",然后whatever

第一个命令几乎是无操作的。它不会影响当前 shell 的变量,不会影响whatever在当前 shell 中解释时的扩展,也不会whatever以您想要的方式产生影响。它只会创建nohup.out(如果尚未创建)。

基本上你需要nohup sh -c 'ID="c"; whatever'&如果需要,请添加)。;当前 shell 不会解释此处。整个单引号字符串最终将成为传递给的选项参数sh -c

我还没有彻底分析你的具体命令来告诉你:

  • 如果我的额外引用在不加思索的情况下干扰了已有的引用(比较如何方便地在 Bash 中单引号或转义整个命令行?(英文):
  • 如果当前 shell 中存在任何不应该用单引号括起来的内容;
  • 如果 看到的新字符串在sh -c的上下文中包含正确的引用sh

总的来说,这些是不同的问题。

答案2

在您编写的“脚本”中,sh -c仅适用于ID="c",即不适用于分号右侧的所有内容。这意味着ID="c"在子进程中设置,该子进程在执行下一个命令之前会被清理。要查看此内容,只需执行sh -c somevar="x"; echo $somevar

对于要共享的变量,它要么需要被导出(参见bash 中“a=b”和“export a=b”的区别)或者具有相同的父进程。

例如,somevar="x"; echo $somevar(无需在子进程中设置变量)会起作用;或者sh -c 'somevar="x"; echo $somevar'也会起作用,因为这两个命令都是的子命令sh -c

相关内容