sudo: source: команда не знайдена


54

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

source /etc/bash.bashrc

Єдине - нові змінні середовища були доступні лише моєму поточному користувачеві - ігнорувалися, коли я використовував sudo. Вони стали доступні для судо лише тоді, коли я закрив свою термінальну сесію і знову приєднався.

Коли я намагаюся використовувати:

sudo source /etc/bash.bashrc

Я отримую помилку:

sudo: source: command not found

Чи є простий спосіб завантажити нові настройки bash для sudo без закриття терміналу та перезавантаження?

- Спочатку я використовував деякі сценарії встановлення, які посилалися на змінні. Я виявив, що, хоча вони могли отримати доступ до змінних, коли я зателефонував безпосередньо до скриптів (хоча це призведе до більш пізньої проблеми зі створенням каталогів, як мені потрібно було викорінювати), викликати сценарії встановлення за допомогою sudo не було б.

Я довів це тестуванням за допомогою цих простих команд:

echo $ENV_VARIABLE
sudo echo $ENV_VARIABLE

Перший виводить значення змінної, а другий нічого не виводить.


Як ви намагалися використовувати змінні з sudo? Зауважте, що якщо ви використовуєте "sudo command $ variable", вона замінить змінну з вашої оболонки, а не з середовища sudo.
Жоао Пінто

Відповіді:


72

Проблема полягає в тому, що sourceце команда вбудування bash (а не програма - як lsабо grep). Я думаю, що один із підходів - це увійти як root та виконати команду source.

sudo -s
source /etc/bash.bashrc

3
Ви праві, що проблема полягає в тому source, що вбудована оболонка. sudo suце своєрідний дивний спосіб сказати це - краще просто сказати, sudo -sякий власний спосіб судо сказати "запустити оболонку як цей користувач". Ваша однорядкова версія не працюватиме, оскільки кожна команда в ній працює оболонкою основного користувача в окремому підпроцесі.
poolie

1
Правильно. Плюс BASH читає / etc / bashrc під час входу. Таким чином, ви можете також використовувати "su" за допомогою -, -l або --login, щоб отримати оточення цього користувача: "sudo su -", щоб стати root або "su - $ ім'я користувача", щоб стати іншим користувачем.

Приклад "один рядок" не буде працювати, оскільки suзапускається нова оболонка, а "джерело" запускається лише після того, як вона припиняється. Перший приклад працює лише в тому випадку, якщо другий рядок використовується всередині кореневої оболонки.
loevborg

sudo -sне кращий, ніж sudo su. Це не матиме жодного ефекту.
loevborg

1
sudo -sмає подібний ефект від запуску оболонки, але мені здається неелегантним складати дві команди "стати іншим користувачем", коли б це було зроблено.
poolie

14

Проблема не в тому, що sourceкоманда вбудована в оболонку. Справа в тому, що це саме те, що насправді кидає вам command not foundпомилку, але це не означає, що працювало б, якби воно було.

Актуальною проблемою є те, як працюють змінні середовища. І вони працюють так: кожен раз, коли починається новий процес, якщо нічого не відбувається, він успадковує оточення свого батька. У зв'язку з цим, використання підзаголовка (наприклад, введення bashвсередині bash-екземпляра) та перегляд виводу файлу envмає дати подібні результати, ніж його батьківський.

Однак, завдяки тому, як це sudoпрацює (як зазначено в його сторінці), sudo намагається зняти середовище користувача та створити середовище "за замовчуванням" для витісняючого користувача, так що командний запуск виконується так, ніби у користувача, який викликав його був користувачем, що викликає (що очікувана поведінка), і, таким чином, працює nautilus, як sudo nautilusслід відкривати папку в /rootпапці, а не /home/yourusername.

Тому:

Робити щось на кшталт sudo source script.shі тоді sudo command, навіть якби це працювало, не було б успішним у встановленні будь-якої змінної на пізніше sudo command.

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


4

За допомогою заміни процесу bash ви можете:

source <(sudo cat /etc/bash.bashrc)

1
Як це допоможе запустити кореневу оболонку з новими налаштуваннями, що саме ОП шукає зробити?
муру

1
ОП насправді запитував, як "... перезавантажити новий профіль ..." з оболонки, яку потрібно використовувати sudoдля доступу до профілю. Вищесказане забезпечує спосіб імпорту профілю, уникаючи вказаної sudo: source: command not foundпроблеми.
TomDotTom

"Єдине - нові змінні середовища були доступні лише моєму поточному користувачеві - ігнорувалися, коли я використовував sudo."
муру

3

Як каже Маркос , ваша основна проблема полягає в тому, що sourceкоманда вбудована в оболонку, яка впливає лише на процес оболонки, в якому вона виконується.

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

sudo bash

2

Закриття та повторне відкриття терміналу не повинно змінювати речі. За замовчуванням sudo позбавляє оточення. Щоб вимкнути це, додайте -E до sudo.


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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.