Обычно я могу отвечать на свои вопросы в Интернете, но на этот раз мой googlefu и понимание меня подвели.
У меня есть сценарий bash, который я собираю, и использую для заполнения правило UDEV. Для этого я использую grep информации udevadm, например:
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 {модель} ==
дает ATTRS {модель} == "BD-CMB UJ160"
.
Здесь вы можете видеть, что результат grep включает завершающие пробелы. Как только я сохраняю результат в переменной и пытаюсь использовать его, я теряю пробелы.
Чтение в Интернете объясняет, что ""
используются для предотвращения потери
, как это :
echo $ drive_model
дает
ATTRS {модель} == "BD-CMB UJ160"
echo "$ drive_model"
дает
ATTRS {модель} == "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"
Кто-нибудь может мне помочь с этим, мне бы очень хотелось получить объяснение любого решения, чтобы я мог узнать
В отличие от некоторых на других языках 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",'
...
С другой стороны, 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"