Я могу использовать переменные внутри {} расширение без 'оценки'?

Когда я обычно должен делать работу как корень, я делаю команды ssh как так:

# ssh backupuser@host.com "hostname ; sudo -S some_backup_script.sh"

Это позволяет регистрироваться sudo действия и способности использовать sudo разрешение в большой степени ограничить то, что может сделать 'sudo' пользователь, входящий в систему. Это - превосходная практика, чтобы иметь эти виды автоматизированных задач с определенными пользователями системы, реализованными для тех определенных функций; т.е. резервный пользователь может использовать tar и gzip, и записать в/tmp каталог, но запрещенный доступ к кошке, энергия, и т.д. (по существу команды, которые позволили бы этому печатать уязвимые данные.)

7
27.02.2014, 03:51
3 ответа

Расширение скобок происходит очень рано во время расширения (фактически первым делом), до расширения переменных. Чтобы выполнить расширение скобок на результате расширения переменной, нужно использовать eval.

Вы можете добиться того же эффекта без eval, если сделаете extensions шаблоном подстановочных знаков, а не скобок. Установите опцию extglob, чтобы активировать кш-подобные шаблоны.

shopt -s extglob
extensions='@(foo|bar)'
ls 1.$extensions
9
27.01.2020, 20:15

Удаление файлов в /usr/share/doc в системах на базе Debian должно быть правильным.

Политика Debian явно указывает в разделе 12,3:

Пакеты не должны требовать наличия каких-либо файлов в / usr/share/doc/для функционирования. [...]

Системный администратор должен иметь возможность удалять файлы в / usr/share/doc/без прерывания программ.

Поскольку диспетчер пакетов также является программой, он должен правильно обрабатывать эту ситуацию (отсутствующие файлы). Это может потребоваться после обновления для повторной очистки /usr/share/doc вручную.

Ответы на этот вопрос Ubuntu объясняют, как можно сохранить место на диске и правильно настроить диспетчер пакетов в системах на базе Debian.

-121--23852-

С помощью поиска

% set keywords {a b c d}
a b c d
% set idx [lsearch -exact $keywords "c"]
2
-121--249904-

Вот способ расширения переменных внутри фигурных скобок без оценки :

end=3
declare -a 'range=({'"1..$end"'})'

У нас теперь есть хороший массив чисел:

for i in ${range[@]};do echo $i;done
1
2
3

Протестировано в bash 4,3,11 но должно работать во всех современных версиях.

3
27.01.2020, 20:15

Другая техника, которую можно использовать в bash и некоторых других оболочках. это использование массива:

$ extensions=(foo bar)
$ ls "${extensions[@]/#/1.}"

Это... ${parameter/pattern/string} (подстановка шаблона) форма расширения параметров.  (К сожалению, это тоже не соответствует POSIX).  [@] указывает, что подстановка должна быть применена к каждому элементу массива, и что разделение между элементами должно быть сохранено.  # в строке pattern действует как ^ в регулярном выражении (т.е. большинство s/old/new/ подстановок); это означает, что подстановка должна происходить только в начале значений параметров.  Таким образом,

$ ls "${extensions[@]/#/1.}"

эквивалентен

$ ls "${extensions[0]/#/1.}" "${extensions[1]/#/1.}"

(поскольку этот массив имеет два элемента, индексированных как 0 и 1) и это расширяется до

$ ls "1.foo" "1.bar"

Цитирование

Кавычки важны, если "расширения" требуют кавычек... т.е. если они (возможно, когда-нибудь) содержат пробелы или символы расширения имени пути (glob/wildcard).  Например, if

$ extensions=("foo bar" "*r")

then

$ ls ${extensions[@]/#/1.}

(без кавычек) расширится до

$ ls 1.foo bar 1.*r

(в котором 1.foo и bar являются отдельными аргументами), а это, в свою очередь, расширяется до

$ ls 1.foo bar 1.anteater 1.bar 1.bear 1.cougar 1.deer 1.grasshopper …

(потому что 1.*r - это подстановочный знак без кавычек).  Для более подробного обсуждения важности цитирования, см. Последствия для безопасности, если забыть заключить переменную в кавычки в оболочках bash/POSIX.

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

$ fnames=(cat dog)
$ ls "${fnames[@]/%/.c}"

расширяется до

$ ls "cat.c" "dog.c"

Но будьте осторожны: % не работает так же, как $ в регулярных выражениях.  Вы должны поместить его в начало образца чтобы ограничить совпадение с концом значения параметра.  Например, если у вас есть

$ fnames=(cat.c dog.c)

и вы хотите получить cat.o и dog.o, не делайте "${fnames[@]/.c%/.o}" - это не сработает.  Делайте

$ ls "${fnames[@]/%.c/.o}"

Но не делайте "${fnames[@]/.c/.o}" (опустив % вообще) либо - если одним из "fnames" является dog.catcher.c, оно будет преобразовано в dog.oatcher.c (поскольку first .c заменяется на .o).

К сожалению, нет простого способа добавить префикс и суффикс, как это можно было бы сделать с

$ ls 1.{foo,bar}.c

См. документацию bash для получения дополнительной информации о переменных, массивах, и преобразованиях, которые можно к ним применить.

2
20.08.2021, 12:56

Теги

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