Bash :Как заключать в кавычки аргументы оболочки с пробелами внутри переменной, содержащей несколько аргументов, без использования массива?

Я хотел сделать то же самое, и вот что я сделал, чтобы это заработало:

Создать/etc/NetworkManager/dispatcher.d/99-user-scripts:

#!/bin/bash
#
#   Run NeworkManager dispatcher scripts from user home directories
#   for logged in users
#   See: https://developer.gnome.org/NetworkManager/stable/NetworkManager.html
#   See: https://unix.stackexchange.com/q/405242
#
for user in $(who | awk '{print $1}' | sort | uniq); do
  scripts_dir="/home/${user}/.config/NetworkManager/dispatcher.d"
  [ ! -d "$scripts_dir" ] && continue
  find $scripts_dir -type f -executable -user $user -perm -u+rwx ! -perm /go+w ! -perm /+s | \
    sort | \
    xargs -I{} sudo -u $user --set-home --preserve-env -- {} $1 $2
done

Установите правильные права доступа к файлу в соответствии с документацией NetworkManager:

$ chmod u+x,go-w,a-s /etc/NetworkManager/dispatcher.d/99-user-scripts

Затем создайте каталог пользовательских скриптов и создайте пользовательский скрипт:

$ mkdir -p ~/.config/NetworkManager/dispatcher.d
$ touch ~/.config/NetworkManager/dispatcher.d/50-my-script
$ chmod u+x,go-w,a-s ~/.config/NetworkManager/dispatcher.d/50-my-script

Вот образец~/.config/NetworkManager/dispatcher.d/50-my-script:

#!/bin/bash
prog="$(basename "${BASH_SOURCE[0]}")"
logger -t $prog -p user.notice "Running ${BASH_SOURCE[0]} $@"
printenv | logger -t $prog -p user.notice # verify environment variables are inherited

Вы можете убедиться, что пример сценария выполняется, проверив системный журнал после того, как произошло сетевое событие.

Ограничения

  • Не будет работать с /rootили не -стандартными путями к домашним каталогам пользователей (легко исправить)
  • Для простоты я решил не реализовывать функциональность до -up.d и до -down.d (возможное улучшение)
  • Я не уверен, что порядок выполнения точно такой же, как /etc/NetworkManager/dispatcher.dскриптов. В документах указано алфавитное, поэтому я использовал sortдля найденных файлов. Вероятно, не огромная проблема, но к вашему сведению.
  • Я использую синтаксис Bash 4+, а не общий код оболочки, потому что это то, с чем я знаком. Я предполагаю, что это может быть сделано для поддержки других оболочек.
  • Я НЕ претендую на безопасность этой реализации!

0
05.11.2021, 00:51
2 ответа

С небольшой поправкой (придется пожертвовать одинарными кавычками):

xargs -n1 printf "[%s]\n" <<<"$MYCONFIG"
[--hi]
[FOO=bar]
[X=ABC 123]

Утилита xargsспособна различать параметры с флагом -n. К сожалению, флаг -Iне позволяет разбивать по пробелам без кавычек.

0
05.11.2021, 05:27
  1. Если вы можете изменить сценарий, но не хотите слишком сильно менять монстра на 2000 строк :, вы должны, конечно , использоватьeval:

    MYCONFIG="--hi FOO=bar 'X=ABC 123'"
    eval "printf '[%s]\n' $MYCONFIG"
    
  2. Если у вас уже есть скрипт, который вы не можете изменить, который использует такую ​​сломанную конструкцию, и вам нужно передать ему аргументы, содержащие пробелы :, вы должны использовать механизм split + glob, создавая файлы с именами аргументов, которые не следует разбивать на пробелы, затем замените их внутри строки шаблоном глобуса, который расширяется до них:

    $ cat script 
    printf '[%s]\n' $MYCONFIG
    $ touch 'X=ABC 123'
    $ MYCONFIG='FOO=BAR *=*' sh script
    [FOO=BAR]
    [X=ABC 123]
    
0
05.11.2021, 06:32

Теги

Похожие вопросы