Я наконец решил эту проблему с помощью псевдонима:
alias sudo='sudo PATH="$PATH" HOME="$HOME" LD_LIBRARY_PATH="$LD_LIBRARY_PATH"'
Обязательно используйте одинарные кавычки, чтобы переменные раскрывались во время вызова, а не при время определения псевдонима.
Это:
(Вы можете увидеть, что задается с помощью: sudo bash -c "echo $ HOME"
)
Я работаю с пользовательскими драйверами и всегда нужно sudo мои тестовые программы для доступа к драйверу. Я не хочу устанавливать тестовые версии библиотек в системную область, поэтому я использую LD_LIBRARY_PATH для настройки определенного тестового каталога по мере необходимости. Я не могу просто установить фиксированный LD_LIBRARY_PATH, мне нужно иметь возможность изменить его и сохранить текущую настройку. Сохранение PATH и HOME дает мне доступ к моей рабочей среде - скриптам и структуре каталогов.
Этот псевдоним позволяет избежать предоставления общих разрешений в sudoers ... и, по-видимому, обходного пути для LD_LIBRARY_PATH нет, в любом случае, независимо от настроек sudoers. Он не работает с sudo внутри скриптов, но при необходимости их можно жестко запрограммировать.
При использовании if [... ]
вы фактически используете утилиту [
(, которая аналогична test
, но требует, чтобы последний аргумент был]
).
[
не понимает запуска вашей функции, он ожидает строки. К счастью, вам вообще не нужно использовать [
здесь (для функции как минимум):
if [ "$docheck" -eq 1 ] && notContainsElement "$fruit" "${blacklist[@]}"; then
...
fi
Обратите внимание, что я также сначала проверяю целое число, чтобы мы могли вообще избежать вызова функции, если $docheck
не равно 1.
Это работает, потому что if
принимает произвольную команду и решает, что делать, исходя из состояния выхода этой команды. Здесь мы используем тест [... ]
вместе с вызовом вашей функции с &&
в -между ними, создавая составную команду. Статус выхода составной команды был бы истинным, если бы и тест [... ]
, и функция возвращали ноль в качестве своих статусов выхода, сигнализируя об успехе.
В качестве примечания к стилю я не хотел бы, чтобы функция проверяла, содержит ли массив не элемент, а если содержит ли элемент, а затем
if [ "$docheck" -eq 1 ] && ! contains "$fruit" "${blacklist[@]}"; then...
Отрицательное значение функционального теста приведет к нарушению логики в тех случаях, когда вы действительно хотите проверить, содержит ли массив элемент(if ! notContainsElement...
).
попробуй
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
,но вы не можете использовать другую команду в рамках теста.
Вот альтернатива, которая может не понравиться некоторым людям. Преобразуйте массив черного списка в строку и посмотрите, совпадает ли строка с удаленным фруктом. Отредактировано для заполнения строк пробелами. Спасибо Скотту за указание на проблему яблока/ананаса.
badlist=" ${blacklist[@]} "
for f in "${list[@]}"
do
if [[ "${badlist/" $f "/}" == "$badlist" ]]
then
echo "$f"
fi
done
Я думаю, что это проще, но не имеет логики &&, которую предпочитают многие.