在以下“一行代码”中,当我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
。