Я хотел бы связаться с (удаленной) неинтерактивной оболочкой через stdin/stdout для запуска нескольких команд и чтения выходов. Проблема в том, что если я использую несколько команд на shell stdin, я не могу обнаружить границы между выходами отдельных команд.Запуск нескольких команд в неинтерактивном сеансе оболочки и анализ вывода
В Python-как псевдо-код:
sh = Popen(['ssh', '[email protected]', '/bin/bash'], stdin=PIPE, stdout=PIPE)
sh.stdin.write('ls /\n')
sh.stdin.write('ls /usr\n')
sh.stdin.close()
out = sh.stdout.read()
Но очевидно out
содержит выходы обеих команд сцепленных, и у меня нет никакого способа надежно их расщепления.
До сих пор моя лучшая идея состоит в том, чтобы вставить \0
байт между выходами:
sh.stdin.write('ls /; echo -ne "\0"\n')
sh.stdin.write('ls /usr; echo -ne "\0"\n')
Тогда я могу разделить out
на нулевых символов.
Другие подходы, которые не работают для меня:
- Я не хочу, чтобы запустить отдельный сеанс SSH за команду, как рукопожатие слишком тяжеловес.
- Я бы предпочел не форсировать параметры ControlMaster на созданных оболочках, чтобы уважать ssh_config конечного пользователя.
- Я бы предпочел, чтобы пользователям не требовалось устанавливать определенные серверные программы.
Есть ли лучший способ запуска нескольких команд за один сеанс и получения отдельных выходов? Существует ли широко развернутая оболочка с каким-то двоичным режимом вывода?
PS. Существует дубликат вопрос, но он не имеет удовлетворительного ответа: Run multiple commands in a single ssh session using popen and save the output in separate files
Если вы можете запустить скрипт на удаленной системе, как Python, вы всегда можете передать команды на него, и есть их выходной закодированный в рассоле или JSON. Ваш подход кажется мне удобным, хотя если вы можете гарантировать, что вывод никогда не будет содержать нулевые символы. Это похоже на многокомпонентную кодировку mime, за исключением того, что использует граничные строки, которые обычно содержат длинные случайные символы, чтобы минимизировать вероятность конфликта. –
Можете ли вы изменить свой процесс на цикл? Для каждой команды запишите команду, сбросьте буфер, затем прочитайте результаты? –
Г-н.Llama, нет способа обнаружить, что выданная команда закончила работу (в отличие от просто работы для производства следующего фрагмента вывода). –