Go to the documentation of this file.00001
00002 import sys
00003 import os
00004 import subprocess as sp
00005 import fcntl
00006
00007 import roslib; roslib.load_manifest("rosshell")
00008 import rospy
00009 from std_msgs.msg import String
00010
00011 import time
00012
00013 def callbackStdIn(msg):
00014 global process
00015
00016
00017 msg.data = msg.data.replace("\\n", "\n")
00018
00019 process.stdin.write(msg.data)
00020 rospy.loginfo("stdin: " +msg.data)
00021
00022 if __name__ == "__main__":
00023
00024 rospy.init_node('rosshellX')
00025
00026 topicStdOut = rospy.get_param('~stdout', "/rosshellX/stdout")
00027 topicStdErr = rospy.get_param('~stderr', "/rosshellX/stderr")
00028 topicStdIn = rospy.get_param('~stdin', "/rosshellX/stdin")
00029 cmd_user = rospy.get_param('~command', "")
00030
00031
00032
00033
00034 if len(cmd_user) == 0:
00035 if len(sys.argv) >= 2:
00036 cmd_user = sys.argv[1]
00037 else:
00038 rospy.logerr("no command to interprete defined, try _command:=\"command\"")
00039 sys.exit()
00040
00041 rospy.loginfo("execute command: " + cmd_user)
00042 rospy.loginfo("stdout on: " + topicStdOut)
00043 rospy.loginfo("stderr on: " + topicStdErr)
00044 rospy.loginfo("stdin on: " + topicStdIn)
00045
00046
00047 cmd_stdbuf = "stdbuf -o L"
00048 cmd = cmd_stdbuf + " " + cmd_user
00049
00050 process = sp.Popen(cmd.split(" "), stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE, bufsize=1)
00051 rospy.loginfo("started process with pid " + process.pid)
00052
00053 pubOUT = rospy.Publisher( topicStdOut, String)
00054 pubERR = rospy.Publisher( topicStdErr, String)
00055 subIN = rospy.Subscriber(topicStdIn, String, callbackStdIn)
00056
00057
00058 fd_out = process.stdout.fileno()
00059 fl = fcntl.fcntl(fd_out, fcntl.F_GETFL)
00060 fcntl.fcntl(fd_out, fcntl.F_SETFL, fl | os.O_NONBLOCK)
00061
00062 fd_err = process.stderr.fileno()
00063 fl = fcntl.fcntl(fd_err, fcntl.F_GETFL)
00064 fcntl.fcntl(fd_err, fcntl.F_SETFL, fl | os.O_NONBLOCK)
00065
00066
00067 while not rospy.is_shutdown():
00068 try:
00069 stdout = process.stdout.readline()
00070 if len(stdout) > 0:
00071 pubOUT.publish(String(stdout))
00072 rospy.loginfo("stdout: " +stdout)
00073 except Exception as e:
00074 pass
00075
00076 try:
00077 stderr = process.stderr.readline()
00078 if len(stderr) > 0:
00079 pubERR.publish(String(stderr))
00080 rospy.logerr("stderr: " +stderr)
00081 except Exception as e:
00082 pass
00083
00084 time.sleep(0.001)
00085
00086
00087 if process.poll()!=0:
00088 break
00089
00090
00091 ret = process.returncode
00092 rospy.signal_shutdown('finish')
00093 sys.exit(ret)