我通常可以在互联网上回答我的问题,但这次我的谷歌搜索能力和理解能力让我失望了。
我正在编写一个 bash 脚本,用于填充 UDEV 规则。为此,我使用 udevadm info 的 grep,如下所示:
install_user=jlivin25
drive_number=sr1
env_ammend=CD
drive_model=$(udevadm info -a -n /dev/sr1 | grep ATTRS{model}==)
udev_insert=$(echo -e "ACTION==\"change\",KERNEL==\""$drive_number"\",SUBSYSTEM==\"block\","\"$drive_model"\",ENV{ID_CDROM_MEDIA_"$env_ammend"}==\"1\",ENV{HOME}=\"/home/"$install_user"\",RUN+=\"/bin/systemctl start "${env_ammend}_ripping.service"\"")
这确实很有效,但是,我遇到的绊脚石是udevadm info -a -n /dev/sr1 | grep ATTRS{model}==
给出的结果ATTRS{model}=="BD-CMB UJ160 "
。
您可以在此处看到 grep 的结果包含尾随空格。当我将结果存储在变量中并尝试使用它时,空格就丢失了。
在网上看到有解释如何""
防止丢失,如下图所示:
echo $drive_model
给出
ATTRS{model}=="BD-CMB UJ160 "
echo "$drive_model"
给出
ATTRS{model}=="BD-CMB UJ160 "
但在填充 UDEV 时我似乎无法让它工作。我得到的结果是:
ACTION=="change",KERNEL=="sr1",SUBSYSTEM=="block"," ATTRS{model}=="BD-CMB UJ160 "",ENV{ID_CDROM_MEDIA_CD}=="1",ENV{HOME}="/home/jlivin25",RUN+="/bin/systemctl start CD_ripping.service"
但我想要的是:
ACTION=="change",KERNEL=="sr1",SUBSYSTEM=="block"," ATTRS{model}=="BD-CMB UJ160
",ENV{ID_CDROM_MEDIA_CD}=="1",ENV{HOME}="/home/jlivin25",RUN+="/bin/systemctl start CD_ripping.service"
有人能帮我解决这个问题吗?我真的很想知道任何解决方案的解释,这样我就可以学习
答案1
与其他一些语言不同,它bash
从左到右逐字逐句地阅读引文。第一个引号为后续字符设定了基础,这些字符将遵守其规则,直到匹配的引号终止引文。从这个意义上讲,你可以说它bash
不 巢引号。
例子:
'ACTION=="change",KERNEL=="' "$drive_number" '",SUBSYSTEM=="block",' ...
^ string one---------------^ ^ string two--^ ^ string three--------^
完整的行看起来会像这样:
udev_insert='ACTION=="change",KERNEL=="'"$drive_number"'",SUBSYSTEM=="block",'"$drive_model"',ENV{ID_CDROM_MEDIA_'"$env_ammend"'}=="1",ENV{HOME}="/home/'"$install_user"'",RUN+="/bin/systemctl start '"${env_ammend}_ripping.service"\"
您还可以使用+=
运算符附加到变量:
udev_insert='ACTION=="change",KERNEL=="'
udev_insert+="$drive_number"
udev_insert+='",SUBSYSTEM=="block",'
...
答案2
另外,printf
这里有一个不错的选择来帮助引用:
user_home=$(getent passwd "$install_user" | cut -d: -f 6)
fmt='ACTION=="change",KERNEL=="%s",SUBSYSTEM=="block","%s",ENV{ID_CDROM_MEDIA_%s}=="1",ENV{HOME}="%s",RUN+="/bin/systemctl start "%s_ripping.service"'
printf -v udev_insert "$fmt" "$drive_number" "$drive_model" "$env_ammend" "$user_home" $env_ammend"