2016-09-02 2 views
0

Я программирую интерфейс Ros в python, и я хотел бы иметь возможность выбрать узел, который я хочу запустить из списка, показывающего все доступные узлы, как только я выберу пакет.Python get bash double-tab complete output

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

rosrun <package-name> \t\t 

С точки зрения кода Python, неправильный пример о том, что я пытаюсь сделать, может быть:

from subprocess import Popen, PIPE 

p = Popen (["rosrun", "<package-name>", "\t\t"], stdout = PIPE, stderr = PIPE) 
out, err = p.communicate() 
print (out.decode ("ascii")) 
print (err.decode ("ascii")) 

Но это не работает, потому что «\ т \ т» не обрабатывается в Popen как он находится в терминале.

Есть ли способ получить эту работу или невозможно эмулировать выполнение двойной вкладки терминала из сценария python?

Можно ли использовать Popen другим способом, чтобы это сделать, или я должен полностью изменить код с помощью других возможностей?

Пожалуйста, помогите мне :)

+0

Я не уверен, что правильный способ сделать это, но я не удивлен такой подход не работает. В этом примере вы запускаете процесс 'rosrun' напрямую и просите его выполнить вкладку, но обычно это оболочка, которая выполняет завершение вкладки перед вызовом программы. Возможно, если вы попытаетесь запустить это с помощью 'shell = True'. , , но я не уверен в этом. –

+0

Да, я написал этот пример только для объяснения того, что мне нужно. Нет, 'shell = True' не решает, я уже пробовал ... Я кое-что прочитал о ** pty **, но я даже не знаю, что это такое. –

+0

Проверьте этот вопрос, который может сделать много чего вы хотите: http://stackoverflow.com/q/9137245/4687135 –

ответ

0

Наконец я решил это сам, я пошел прямо бросить ROS собственного кода и выяснил, как она формирует выходной сигнал завершения Баша.

Мой код теперь так:

from subprocess import Popen, PIPE 
package = "<package>" 
comm = str("catkin_find --first-only --without-underlays --libexec " + package).split() 
out, err = Popen (comm, stdout = PIPE, stderr = PIPE).communicate() 
out = out.decode ("ascii") 
if (out.strip() == ""): 
    return 
comm = "find -L " + out.strip() + " -type f -exec basename {} ';'" 
out, err = Popen (comm, shell = True, stdout = PIPE, stderr = PIPE).communicate() 
out = out.decode ("ascii") 
print (out.strip()) 

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

Я надеюсь, что это может быть полезно и для других.

Спасибо за советы :)