在变量中使用带有尾随空格的值,保留空格

在变量中使用带有尾随空格的值,保留空格

我通常可以在互联网上回答我的问题,但这次我的谷歌搜索能力和理解能力让我失望了。

我正在编写一个 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"

相关内容