su -s '/ bin / bash' продолжает использовать оболочку в / etc / passwd

Проблема с вашей попыткой заключается в том, что того, что вы называете "методом здесь-файла", просто не существует. Здесь документы являются особенностью синтаксиса языка программирования оболочки. Такие приложения, как cat, не интерпретируют их.

Рассмотрим сценарий оболочки с документом «здесь»:

cat <<EOF
hello
world
EOF

Это работает следующим образом: при анализе сценария интерпретатор оболочки видит синтаксическую конструкцию документа «здесь». Когда он запускает эти строки кода, интерпретатор собирает данные и передает их в качестве входных данных в cat. В зависимости от оболочки это по существу эквивалентно либо

echo 'hello
world
' >/tmp/heredoc.tmp
cat </tmp/heredoc.tmp
rm /tmp/heredoc.tmp

(но с более разумным управлением временным файлом), либо

echo 'hello
world
' | cat

. Если у вас есть echo EOF, и вы хотите, чтобы это указывало на конец здесь document, то вывод команды echoдолжен быть оболочкой.

{
  echo 'cat <<EOF'
  echo hello
  echo world
  echo EOF
} | sh

Это работает, но редко бывает полезным.

Ничто из этого не поможет вам сделать то, что вы намеревались сделать.В этом документе нет ничего волшебного, из-за чего он заканчивается «сложнее», чем любой другой ввод. Конец файла — это не маркер, который передается по входному каналу, это состояние входного канала. Когда входными данными является обычный файл, условие конца файла срабатывает, когда приложение пытается прочитать последний байт файла. Когда ввод представляет собой канал (именованный или нет), условие конца файла срабатывает, когда приложение пытается прочитать, но производитель закрыл канал.

Обычно достаточно написать

producer | consumer

Когда производительзавершает работу, конец записи канала будет закрыт, так как он больше не открыт ни для одного процесса. Если вы хотите, чтобы канал был закрыт раньше, сделайте так, чтобы производитель закрыл свой стандартный вывод (exec >&-в sh, close(1)в C).

Обратите внимание, что для достижения конца файла в канале все процессы, у которых был открыт конец канала для записи, должны закрыть его. Если производитель запускает фоновые процессы, вы можете установить флаг close-on-exec для канала (fcntl(1, F_SETFD, fcntl(1, F_GETFC, 0) | FD_CLOEXEC)) перед их разветвлением. .

0
21.12.2018, 00:26
1 ответ

Хотел бы я отдать 50% должного @Basile Starynkevitch или даже если бы он написал отдельные ответы. Потому что одно из его предложений вывело меня на правильный путь.

1 -Как говорит @Basile Starynkevitch, я смог загрузить машину, и в GRUB я нажал «e», чтобы изменить параметры загрузки. В строке, начинающейся с «linux», я добавил параметр:

init=/bin/bash

Это загрузило меня в корневую оболочку bash. Прогресс!

2 -Будучи пользователем root в файловой системе, вы по-прежнему не сможете ничего редактировать, потому что файловая система монтируется только для чтения (, даже если вы удалите эту опцию из GRUB, которую я обнаружил, но не исследовал почему )так что вы должны ввести:

# mount -o remount,rw /

Затем вы можете перейти к:

3 -Отредактируйте файл /etc/passwd

Как говорит @Basile Starynkevich:

BTW the right thing to do to change a shell is chsh

Он прав. Но я только что сделал

# vi /etc/passwd

потому что я обычно не делаю одну и ту же глупость дважды.

2
28.01.2020, 02:33

Теги

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