sudo: источник: команда не найдена

55

Я обновлял некоторые профили по умолчанию для bash, и из руководств, которые я отслеживал, я увидел, что могу перезагрузить новый профиль с новыми настройками среды, используя:

source /etc/bash.bashrc

Единственное, что - новые переменные окружения были доступны только моему текущему пользователю и игнорировались, когда я использовал sudo. Они стали доступны только для sudo, когда я закрыл сеанс терминала и вернулся.

Когда я пытаюсь использовать:

sudo source /etc/bash.bashrc

Я получаю ошибку:

sudo: source: command not found

Есть ли простой способ загрузить новые настройки профиля bash для sudo, не закрывая терминал и не перезагружая его?

- Первоначально я использовал несколько сценариев установщика, которые ссылались на переменные. Я обнаружил, что, хотя они могли обращаться к переменным, когда я вызывал сценарии напрямую (хотя это могло вызвать более позднюю проблему с созданием каталогов, так как мне нужно было быть пользователем root), вызов сценариев установки с использованием sudo не будет.

Я доказал это, протестировав эти простые команды:

echo $ENV_VARIABLE
sudo echo $ENV_VARIABLE

Первая выдаст значение переменной, но вторая ничего не выдаст.

HorusKol
источник
Как вы пытались использовать переменные из sudo? Обратите внимание, что если вы используете «команду sudo $ variable», она заменит переменную из вашей оболочки, а не из среды sudo.
Жоау Пинту

Ответы:

73

Проблема в том, что sourceэто встроенная команда bash (а не программа lsили как grep). Я думаю, что один из подходов состоит в том, чтобы войти в систему как root, а затем выполнить исходную команду.

sudo -s
source /etc/bash.bashrc
Маркос Рорис Младший
источник
3
Вы правы, проблема в том, что sourceвстроенная оболочка. sudo suэто своего рода странный способ сказать это - лучше просто сказать, sudo -sчто это собственный способ сказать sudo «запустить оболочку от имени этого пользователя». Ваша однострочная версия не будет работать, потому что каждая из команд в ней запускается оболочкой основного пользователя в отдельном подпроцессе.
пул
1
Правильно. Плюс BASH читает / etc / bashrc во время входа в систему. Таким образом, вы можете также использовать 'su' с ключами -, -l или --login, чтобы получить среду этого пользователя: 'sudo su -', чтобы стать root, или 'su-$ username', чтобы стать другим пользователем.
Пример «одной строки» не будет работать, потому что suзапускает новую оболочку, а «source» запускается только после ее завершения. Первый пример работает, только если вторая строка используется внутри корневой оболочки.
loevborg
sudo -sне лучше sudo su. Это не будет иметь никакого эффекта в любом случае.
loevborg
1
sudo -sимеет аналогичный эффект запуска оболочки, но мне кажется неуместным сложить две команды «стать другим пользователем», когда одна из них сделает это.
пул
14

Проблема не в том, что sourceэто встроенная команда оболочки. Факт, что это действительно то , что на самом деле выдает command not foundошибку, но это не значит, что она будет работать, если бы это было.

Актуальная проблема заключается в том, как работают переменные среды. И они работают так: каждый раз, когда запускается новый процесс, если ничего не происходит, он наследует среду своего родителя. Из-за этого использование подоболочки (например, ввод bashвнутри экземпляра bash) и просмотр выходных данных envдолжны давать аналогичные результаты, чем его родитель.

Однако из-за того, как sudoработает (как указано в его man-странице), sudo пытается лишить пользователя среды и создать среду «по умолчанию» для вытесняющего пользователя, чтобы команда запускалась так, как если бы пользователь, который ее вызвал, имел был вызывающим пользователем (что является ожидаемым поведением) и, таким образом, запустил nautilus, так как sudo nautilusдолжен открывать папку в /rootпапке, а не /home/yourusername.

Так:

Выполнение чего-то подобного, sudo source script.shа затем sudo command, даже если это сработало, не помогло бы установить любую переменную на более позднюю sudo command.

Чтобы передать переменные окружения, вы можете либо сказать sudo сохранить окружение (через -Eкоммутатор; и иметь соответствующие разрешения в файле sudoers) и / или установить его для команды as sudo VAR1=VALUE1 VAR2=VALUE2 command.

ssice
источник
4

Используя замену процесса bash, вы можете сделать:

source <(sudo cat /etc/bash.bashrc)
TomDotTom
источник
1
Как это могло бы помочь запустить корневую оболочку с новыми настройками, что ОП хочет сделать?
Муру
1
ОП фактически спрашивал, как «... перезагрузить новый профиль ...» из оболочки, которую необходимо использовать sudoдля доступа к профилю. Вышеуказанное позволяет импортировать профиль, избегая sudo: source: command not foundупомянутой проблемы.
TomDotTom
«Единственное, что - новые переменные окружения были доступны только моему текущему пользователю - и игнорировались, когда я использовал sudo».
Муру
3

Как говорит Маркос , ваша главная проблема в том, что sourceэто встроенная команда оболочки, которая влияет только на процесс оболочки, в котором она выполняется.

Простое решение - просто запустить новую оболочку с правами root, и bash автоматически прочитает ее /etc/bash.bashrcпри запуске. Это так просто, как просто сказать

sudo bash
poolie
источник
2

Закрытие и повторное открытие терминала не должны ничего менять. По умолчанию sudo удаляет окружение. Чтобы отключить это, добавьте -E в sudo.

psusi
источник
2

Ошибка возникает из-за того, что двоичный файл, который вы пытаетесь вызвать из командной строки, является только частью переменной PATH текущего пользователя, но не является частью PATH корневого пользователя.

Вы можете убедиться в этом, найдя путь к двоичному файлу, к которому вы пытаетесь получить доступ. В моем случае я пытался назвать "bettercap-ng". Итак, я побежал,

$ which bettercap-ng
/home/user/work/bin/bettercap`

Я проверил, является ли это местоположение частью PATH моего корневого пользователя.

$ sudo env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

Поэтому sudo не может найти двоичный файл, который я пытаюсь вызвать из командной строки. Следовательно, возвращает ошибку команда не найдена.

Вы можете указать sudo использовать PATH текущего пользователя при вызове двоичного файла, как показано ниже.

sudo -E env "PATH=$PATH" [command] [arguments]

На самом деле из него можно сделать псевдоним:

alias mysudo='sudo -E env "PATH=$PATH"'

Также возможно назвать псевдоним сам sudo, заменив оригинальный sudo.

Анонимный утконос
источник