Shell: Используя функцию с параметрами в if

Я наконец решил эту проблему с помощью псевдонима:

alias sudo='sudo PATH="$PATH" HOME="$HOME" LD_LIBRARY_PATH="$LD_LIBRARY_PATH"'

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

Это:

  • сохраняет HOME (который в противном случае устанавливается в / root)
  • сохраняет PATH (который в противном случае устанавливается на «безопасный» путь в suders)
  • сохраняет текущий значение LD_LIBRARY_PATH (которое в противном случае становится пустым)

(Вы можете увидеть, что задается с помощью: sudo bash -c "echo $ HOME" )

Я работаю с пользовательскими драйверами и всегда нужно sudo мои тестовые программы для доступа к драйверу. Я не хочу устанавливать тестовые версии библиотек в системную область, поэтому я использую LD_LIBRARY_PATH для настройки определенного тестового каталога по мере необходимости. Я не могу просто установить фиксированный LD_LIBRARY_PATH, мне нужно иметь возможность изменить его и сохранить текущую настройку. Сохранение PATH и HOME дает мне доступ к моей рабочей среде - скриптам и структуре каталогов.

Этот псевдоним позволяет избежать предоставления общих разрешений в sudoers ... и, по-видимому, обходного пути для LD_LIBRARY_PATH нет, в любом случае, независимо от настроек sudoers. Он не работает с sudo внутри скриптов, но при необходимости их можно жестко запрограммировать.

8
13.07.2018, 17:20
3 ответа

При использовании if [... ]вы фактически используете утилиту [(, которая аналогична test, но требует, чтобы последний аргумент был]).

[не понимает запуска вашей функции, он ожидает строки. К счастью, вам вообще не нужно использовать [здесь (для функции как минимум):

if [ "$docheck" -eq 1 ] && notContainsElement "$fruit" "${blacklist[@]}"; then
 ...
fi

Обратите внимание, что я также сначала проверяю целое число, чтобы мы могли вообще избежать вызова функции, если $docheckне равно 1.

Это работает, потому что ifпринимает произвольную команду и решает, что делать, исходя из состояния выхода этой команды. Здесь мы используем тест [... ]вместе с вызовом вашей функции с &&в -между ними, создавая составную команду. Статус выхода составной команды был бы истинным, если бы и тест [... ], и функция возвращали ноль в качестве своих статусов выхода, сигнализируя об успехе.

В качестве примечания к стилю я не хотел бы, чтобы функция проверяла, содержит ли массив не элемент, а если содержит ли элемент, а затем

if [ "$docheck" -eq 1 ] && ! contains "$fruit" "${blacklist[@]}"; then...

Отрицательное значение функционального теста приведет к нарушению логики в тех случаях, когда вы действительно хотите проверить, содержит ли массив элемент(if ! notContainsElement...).

15
27.01.2020, 20:09

попробуй

if notContainsElement "$fruit" "${blacklist[@]}" && test "$docheck" = 1
then
  • -aопция не является ни оболочкой, ни опцией test

здесь у вас есть тест из двух частей

notContainsElement "$fruit" "${blacklist[@]}"
test $docheck = 1 ## or [ $docheck = 1 ]

вы связываете затем в ifс помощью

if cmd1 && cmd2

как указано -aявляется тестовой опцией, но может использоваться только с другой тестовой опцией, поэтому вы можете использовать

if [ "$a" -lt "$b" -a "$a" -lt "$c" ]

, чтобы проверить, что $aменьше, чем $bи $c,но вы не можете использовать другую команду в рамках теста.

3
27.01.2020, 20:09

Вот альтернатива, которая может не понравиться некоторым людям. Преобразуйте массив черного списка в строку и посмотрите, совпадает ли строка с удаленным фруктом. Отредактировано для заполнения строк пробелами. Спасибо Скотту за указание на проблему яблока/ананаса.

badlist=" ${blacklist[@]} "
for f in "${list[@]}"
do
    if [[ "${badlist/" $f "/}" == "$badlist" ]]
    then
        echo "$f"
    fi
done

Я думаю, что это проще, но не имеет логики &&, которую предпочитают многие.

0
27.01.2020, 20:09

Теги

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