#linux #shell #expect
Вопрос:
Я пытался использовать expect, и, похоже, он не работает вне tty в определенном контексте
Это связано с попыткой вызвать команду без взаимодействия для создания пакета makepkg
$ makepkg -Ccfi --noconfirm
==> Installing package test-delta with pacman -U...
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
sudo: a terminal is required to read the password; either use the -S option to re
ad from standard input or configure an askpass helper
sudo: a password is required
==> WARNING: Failed to install built package(s).
Хотя я смог правильно вызвать его с помощью следующего:
$ sudo -S -v <<< У меня все еще были подобные проблемы с подсказками пароля при выполнении программ, не связанных с Bash. И то, что я думал, было бы легко исправить, оказалось не всегда работающим... Мне нужно, чтобы это обобщенное решение работало должным образом Ниже приведен сценарий ожидания...
cat > run.sh <<"EOF" expect -c 'spawn makepkg -Ccfi --noconfirm; expect "*password*"; send "passwordn"; interact' EOF
И он успешно запускается на терминале, устанавливая пакет
$ ./run.sh ... ==> Installing package test-delta with pacman -U... [sudo] password for op: loading packages... warning: test-delta-1.0.0-1 is up to date -- reinstalling resolving dependencies... looking for conflicting packages... Packages (1) test-delta-1.0.0-1 Total Installed Size: 0.00 MiB Net Upgrade Size: 0.00 MiB :: Proceed with installation? [Y/n] (1/1) checking keys in keyring [##############################] 100% ...
Запуск сценария на tty, похоже, сработал. Однако на самом деле этот сценарий выполнялся
toast
чем-то вроде бегуна задач, смешанного с Докером , и там он потерпел бы неудачу. (Я действительно пытался смоделировать поведение Тоста в bash и никак не мог заставить его потерпеть неудачу) Вывод выглядит так, когда я пытаюсь запустить его через тост:➤ toast --shell [INFO] Ready to run 2 tasks: init and main. [INFO] Running task init… [INFO] Running task main… spawn makepkg -Ccfi --noconfirm ==> Making package: test-delta 1.0.0-1 (Sat 29 May 2021 01:58:26 AM UTC) ... ==> Finished making: test-delta 1.0.0-1 (Sat 29 May 2021 01:58:27 AM UTC) ==> Installing package test-delta with pacman -U... We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for op: [INFO] Preparing a shell… [op@9205d39656e4 scratch]$ pacman -Qi test-delta error: package 'test-delta' was not found
I tried to simulate it's failing behavior manually for those that don't have the program installed. So I try to run without an attachment to current tty
# https://superuser.com/a/1430883 (setsid ./run.sh) </dev/null |amp; cat
The above does not fail, so I also tried the following to make it fail
(setsid ./run.sh) <>/dev/null
Both unexpectedly worked, so I looked at toast and it seemed to execute commands like this.
So I try to use
sh
as well...sh -c '(setsid ./run.sh) </dev/null |amp; cat'
AH (╯°□°)╯︵ ┻━┻. This command succeeds while Toast fails? How does the command ran within Toast fails? I'm not sure what to do at this point. Some other tricks like
unbuffer -p
didn't seem to change things either...I don't think it's due to any process namespaces created by Docker? I don't know what to guess at this point, I don't think Toast is doing anything special? I recon others have had similar problems that may be familiar with this issue - but if you wish to reproduce this on your own, I have the following setup in a directory:
You can replicate this with this
toast.yml
fileimage: archlinux default: main tasks: init: command: | set -Eeuo pipefail pacman -Syu --noconfirm base-devel sudo man-db expect sed -ie 's/# %sudo/%sudo/g' /etc/sudoers groupadd sudo useradd -m op -s /bin/bash -G sudo chpasswd <<< 'op:password' main: dependencies: [ init ] cache: false user: op mount_paths: - . command: | ./run.sh
This
PKGBUILD
file# Maintainer: Edwin Kofler <edwin@kofler.dev> pkgname='test-delta' pkgver='1.0.0' pkgrel='1' pkgdesc='Desc' arch=('any') license=('unknown') depends=(bash) # prepare() { # : # } # build() { # : # } # check() { # : # } package() { mkdir "$pkgname-$pkgver" cd "$pkgname-$pkgver" mkdir -p "$pkgdir/usr/bin" cat > "$pkgdir/usr/bin/test-delta" <<< "echo 'WORKING WORKING WORKING WORKING' -------------------" chmod x "$pkgdir/usr/bin/test-delta" }
и этот
run.sh
файлexpect -c 'spawn makepkg -Ccfi --noconfirm; expect "*password*"; send "passwordn"; interact'
Запустив
toast --shell
в том же каталоге...$ toast --shell ... [INFO] Preparing a shell… [op@69bee81d643f scratch]$ pacman -Qi test-delta error: package 'test-delta' was not found
Комментарии:
1.
sudo
без-S
использования (и требует)/dev/tty
. Это отдельно от stdin,out,err,поэтому все ваши различные и творческие способы перенаправления stdin, out не влияют на это. И не делаетsetsid
, что (только) влияет на доставку сигналов от драйвера tty, которые здесь не имеют отношения к делу. Я почти уверен, что docker влияет на /dev/tty и является вашей проблемой здесь , но я сам не использую docker и не знаю правильного решения.2. Есть какая-то особая причина, по которой вы просто не работаете
makepkg
какroot
?
passwordn'
$ source makepkg -Ccfi --noconfirm
У меня все еще были подобные проблемы с подсказками пароля при выполнении программ, не связанных с Bash. И то, что я думал, было бы легко исправить, оказалось не всегда работающим… Мне нужно, чтобы это обобщенное решение работало должным образом
Ниже приведен сценарий ожидания…
И он успешно запускается на терминале, устанавливая пакет
Запуск сценария на tty, похоже, сработал. Однако на самом деле этот сценарий выполнялся toast
чем-то вроде бегуна задач, смешанного с Докером , и там он потерпел бы неудачу. (Я действительно пытался смоделировать поведение Тоста в bash и никак не мог заставить его потерпеть неудачу) Вывод выглядит так, когда я пытаюсь запустить его через тост:
I tried to simulate it’s failing behavior manually for those that don’t have the program installed. So I try to run without an attachment to current tty
The above does not fail, so I also tried the following to make it fail
Both unexpectedly worked, so I looked at toast and it seemed to execute commands like this.
So I try to use sh
as well…
AH (╯°□°)╯︵ ┻━┻. This command succeeds while Toast fails? How does the command ran within Toast fails? I’m not sure what to do at this point. Some other tricks like unbuffer -p
didn’t seem to change things either…
I don’t think it’s due to any process namespaces created by Docker? I don’t know what to guess at this point, I don’t think Toast is doing anything special? I recon others have had similar problems that may be familiar with this issue — but if you wish to reproduce this on your own, I have the following setup in a directory:
You can replicate this with this toast.yml
file
This PKGBUILD
file
и этот run.sh
файл
Запустив toast --shell
в том же каталоге…
Комментарии:
1.
sudo
без-S
использования (и требует)/dev/tty
. Это отдельно от stdin,out,err,поэтому все ваши различные и творческие способы перенаправления stdin, out не влияют на это. И не делаетsetsid
, что (только) влияет на доставку сигналов от драйвера tty, которые здесь не имеют отношения к делу. Я почти уверен, что docker влияет на /dev/tty и является вашей проблемой здесь , но я сам не использую docker и не знаю правильного решения.2. Есть какая-то особая причина, по которой вы просто не работаете
makepkg
какroot
?