Хобрук: Ваш путь к мастерству в программировании

PHP, использующий shell_exec (bash read), работает с tty, но не тогда, когда ввод передается по конвейеру и не имеет новой строки

TL;DR -- echo -n abc | bash -c 'read -s x && echo -n \$x' не выводит abc.

У меня есть скрипт PHP CLI, которому нужно прочитать пароль со стандартного ввода.

<?php

function quiet_read_stdin ()
{
    return shell_exec ("bash -c 'read -s x && echo -n \$x'");
}

print "got: ###".quiet_read_stdin ()."###\n";
?>

Если я запущу это в терминале и введу, скажем, «xyz»:

$> php /tmp/foo.php
got: ###xyz###

Как и ожидалось, это тоже работает

$> echo xyz | php /tmp/foo.php
got: ###xyz###

Но это не так.

$> echo -n xyz | php /tmp/foo.php
got: ######

Это вызывает проблемы в моем скрипте в том случае, если секретный ключ хранится в файле без новой строки, что эквивалентно php /tmp/foo.php < keyfile.

Это не работает (Inappropriate ioctl for device):

system ('stty -echo');
$password = trim (fgets (STDIN));
system ('stty echo');

Я не хочу обманывать его, вставляя новую строку на любом этапе. Как мне изменить quiet_read_stdin, чтобы он работал независимо от того, есть ли в конце ввода новая строка? Решение только для Linux подходит.


  • Вы не можете заставить read -s работать, когда ввод заканчивается преждевременно (до LF). Поэтому вам нужно искать другое решение для чтения из STDIN с отключенным локальным эхом. 21.11.2016
  • над какой ОС/дистрибутивом и оболочкой вы работаете? php версия? 21.11.2016

Ответы:


1

Для меня это работает:

$ cat test.php
<?php
// ignore error message
// stty: standard input: Inappropriate ioctl for device    
shell_exec('stty -echo 2>/dev/null'); 

$io = fopen("php://stdin", "r");
$password = fgets($io);
echo "foo: $password\n";

shell_exec('stty echo 2>/dev/null');

$ echo -n "xyz" | php test.php
foo: xyz

$ php test.php          # typing: abc[ENTER]
foo: abc
20.11.2016
  • И, как говорится в моем вопросе, stty -echo у меня не работает. 21.11.2016
  • в любом случае, оставлю это здесь, так как это может помочь другим. использовал его во всех моих сценариях, и он никогда не подводил меня (пока). 21.11.2016
  • @spraff вы пробовали пример? При передаче данных в STDIN вы можете спокойно игнорировать сообщение об ошибке, так как передаваемое содержимое все равно не отображается. И когда вы вызываете клавиатуру сценария в интерактивном режиме (без конвейера), stty -echo должен работать. Для меня сообщение об ошибке появляется только при передаче контента и поэтому может быть проигнорировано. 21.11.2016

  • 2

    Это будет читать строку с новой строкой или без нее и всегда печатать ее с новой строкой

    readslient.sh:

    #!/bin/bash
    
    while IFS= read -r -s LINE || [[ -n "$LINE" ]]; do
        echo $LINE
    done
    

    Затем PHP может

    $pw = rtrim (shell_exec ("readslient.sh"));
    

    Я не понимаю, как сделать это однострочным для shell-exec, но было бы неплохо не иметь для этого отдельный файл.

    21.11.2016
    Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

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

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...