Поиск по сайту:

Вы не можете использовать выход из системы в сценарии Bash, поэтому используйте эти обходные пути


Ключевые выводы

  • Команда выхода из системы Linux не работает в сценариях, поскольку они выполняются в оболочках без входа в систему.
  • В оболочке входа в консоль вы можете использовать команду exec для запуска сценария, и после его завершения вы выйдете из системы.
  • Альтернативные методы включают использование исходного кода или добавление команды выхода из системы в командную строку.

Команда выхода из системы Linux не работает внутри сценариев Bash. Это редкость, но иногда вам может понадобиться эта функция. Вот три способа обойти эту проблему и выйти из скрипта.

Почему выход из системы не работает в скриптах

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

Проще говоря, вы не можете выйти из оболочки без входа в систему. Если в оболочке нет концепции входа в систему, она не сможет вас выйти из системы.

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

Мы можем увидеть это довольно легко. Это приглашение для входа в систему на компьютере под управлением Arch Linux без установленной графической среды рабочего стола. Он использует оболочку Bash. Я вошел в систему и собираюсь нажать Enter в команде выхода.

logout

Как и следовало ожидать, меня снова выбрасывает на приглашение для входа в систему.

Очевидно, что я использую оболочку входа в систему. Давайте снова войдем в систему и проверим содержимое скрипта lo.sh. Тогда мы его запустим.

cat lo.sh
./lo.sh

Bash жалуется, что мы не можем использовать выход из системы без входа в систему. Несмотря на то, что наш скрипт определенно запускался из оболочки входа в систему, он не работает. Мы не вышли из системы.

Он также не будет работать в окне эмулятора терминала на компьютере с графической средой рабочего стола. В данном случае это Ubuntu с рабочим столом GNOME.

logout

Я сказал, что у вас есть только одна оболочка для входа. Это не совсем так. Существуют сценарии, когда на вашем компьютере может быть запущено несколько оболочек входа в систему, но у вас есть только одна оболочка входа в систему для каждого экземпляра пользователя.

Каждому пользователю нужна собственная оболочка входа, чтобы он мог входить и выходить. Можно войти на один и тот же компьютер более одного раза под одним и тем же пользователем. Если на вашем компьютере настроен SSH для поддержки удаленного доступа, вы можете снова войти в систему через SSH на свой локальный компьютер через окно терминала.

ssh dave@localhost
who
logout
who

После входа в систему мы запускаем команду who, чтобы получить список текущих пользователей, затем выходим из системы и снова запускаем who. Мы видим, что у нас временно появился дополнительный пользователь. У этого пользователя есть собственная оболочка входа. Но это не поможет нам в нашем сценарии. Это единственный пользователь, который может получить доступ к этой оболочке, и они увидят то же поведение, что мы только что видели.

Как выйти из системы с помощью exec

Итак: выход из системы должен использоваться в оболочке входа в систему, но наш скрипт не будет запускаться в оболочке входа в систему, даже если он запущен из нее.

Что мы можем сделать, так это запустить наш скрипт с помощью exec. Это не соответствует обычному процессу создания оболочки для запуска сценария. Текущая оболочка заменяется командой, которую запускает exec. Оболочка выбрасывается. Когда команда завершается, она не может вернуться в несуществующую оболочку. Если мы сделаем это из оболочки входа в систему, мы выйдем из системы.

Нам нужен сценарий для экспериментов. Скопируйте этот тривиальный скрипт в свой любимый редактор, а затем сохраните его как «lo.sh».

#!/bin/bash
logout

Мы будем использовать chmod, чтобы сделать его исполняемым.

chmod +x lo.sh

Сценарий завершается с ошибкой, выдавая уже знакомое сообщение об ошибке:

./lo.sh

Если мы запустим его с помощью exec, окно терминала закроется, когда скрипт перестанет работать.

exec ./lo.sh

Конечно, на нашем консольном компьютере Arch мы не используем эмулятор терминала. exec заменяет нашу оболочку входа в систему сценарием.

Когда сценарий завершится, нам будет представлено новое приглашение для входа в систему. Таким образом, он работает для входа в консоль на компьютерах Linux без установленной графической среды рабочего стола. Поможет ли это нам на нашем компьютере с Ubuntu, на котором работает GNOME?

Да, это так. В GNOME мы можем нажать Ctrl+Alt+FnKey, чтобы открыть точно такую же полноэкранную консоль оболочки входа в систему. FnKey может быть от F3 до F6.

Мы можем войти в систему и использовать ту же команду, что и на нашем компьютере Arch.

exec lo.sh

Мы выходим из системы и возвращаемся к приглашению для входа в консоль. Нажатие Ctrl+Alt+F1 вернет вас в сеанс GNOME. Вам нужно будет ввести пароль, чтобы восстановить доступ.

Обратите внимание, что вы вернулись в сеанс GNOME таким, каким он был до нажатия Ctrl+Alt+F3. Выход из вашего сеанса GNOME не завершен, но он защищен паролем.

Если вы не хотите, чтобы пользователь сеанса GNOME оставался в системе, выйдите из системы перед запуском сценария. Вы можете нажать Ctrl+Alt+F3 на экране входа в Ubuntu, войти в консоль и запустить скрипт.

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

Вы можете использовать выход вместо выхода из системы или вообще не использовать ни одну команду. Как только сценарий завершится, вы выйдете из системы. Если в вашем скрипте есть ветки выполнения и он может завершаться в разных местах, вы можете использовать выход для завершения каждого из возможных путей выполнения.

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

Как выйти из системы, используя источник

Использование исходной команды Linux интерпретирует команды внутри вашего сценария без запуска сценария в оболочке. Команды интерпретируются текущей оболочкой.

Откройте окно консоли, как указано выше, используя Ctrl+Alt+F3, и используйте исходную команду для интерпретации команд вашего скрипта.

source ./lo.sh

Вы можете использовать слово «источник» или точку.

. ./lo.sh

При использовании этого метода вам потребуется выйти из сценария или выйти из него. Само по себе завершение сценария не приведет к выходу из системы.

Как выйти из системы с помощью функции Bash

Существует способ запустить любой скрипт и выйти из него после завершения, не вызывая выхода из системы или не выходя из самого скрипта. Сохраните этот скрипт как simple.sh.

#!/bin/bash
echo "This script doesn't call any other commands."

Сделайте его исполняемым, набрав:

chmod +x simple.sh

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

./simple.sh; logout

Когда наш скрипт завершает работу, мы выходим из системы.

Если вы делаете это часто, было бы удобно создать такую небольшую функцию Bash.

run-logout () {
  $1; logout
}

Вы можете вызвать эту функцию и передать ей имя скрипта. Когда вы сделаете это в консоли входа в систему, вы выйдете из системы после завершения сценария.

run-logout simple.sh

Быстрый обзор

Если вы хотите, чтобы сценарий выполнялся до завершения в ваше отсутствие и чтобы пользователь выходил из системы после его завершения, чтобы ни один пользователь вообще не входил в систему, выполните следующие действия.

  • Выйдите из системы всех пользователей.
  • На экране входа в GNOME нажмите Ctrl+Alt+F3, чтобы открыть окно консоли входа.
  • Авторизоваться.
  • Запустите скрипт одним из трех методов, показанных выше.

Статьи по данной тематике: