我正在尝试编写一个批处理脚本来创建新的终结器终端,然后在每个终端中运行一个进程。我希望他们继续在后台运行,直到我决定杀死他们。
我希望第一个运行 10 秒,然后同时创建一堆其他终结器进程。
这第一部分很有效,但现在我希望最后能够按 Enter 并向我启动的每个进程发送一个 SIGINT。我想不出适用于此目的的命令。
#!/bin/sh
echo "Running Teleop... (MAY TAKE SEVERAL SECONDS TO INITIALIZE)"
terminator -T "gazebo" -e "roslaunch cob_bringup_sim robot.launch
robot:=cob4-8 robot_env:=ipa-apartment; bash" &
#wait 10 secons before starting nav and rviz otherwise will get error
((sleep 10) &&
(terminator -T "navigation" -e "roslaunch cob_navigation_global
2dnav_ros_dwa.launch robot:=cob4-5 robot_env:=ipa-apartment; bash" &
terminator -T "rviz" -e "roslaunch cob_navigation_global rviz.launch;
bash" &
terminator -T "arm_controller" -e "roslaunch cob_moveit_bringup
demo.launch rviz_tutorial:=true robot:=cob4-8; bash" &
terminator -T "control_nodes" -e "cd catkin_ws; rosrun first_pkg
control_nodes; bash" &
terminator -T "controller" -e "cd catkin_ws; rosrun first_pkg
controller; bash" &
terminator -T "joystick" -e "rosrun joy joy_node; bash" &
#spawn objects
terminator -T "spawn_objects_launch" -e "roslaunch
cob_default_env_config upload_object_locations.launch robot_env:=ipa-
apartment; rosrun cob_bringup_sim spawn_object.py tomato_sauce;
bash")) &
(
echo Press any key to to shutdown all processes
read varname
echo Shutting down...
#terminating all child processes
)
这些是 ROS 命令,但我认为在这种情况下它们与通用命令没有区别。我意识到代码非常混乱,如果您看到它有任何其他问题,我会很高兴听到它。谢谢!
当以非交互方式运行时(例如在脚本中),bash 禁用作业控制,因此很容易杀死后台进程,例如Kill all background jobs或How to kill all jobs in bash? 默认情况下不会工作。
我要做的第一件事是通过将 sh-bang 行更改为:
接下来,让我们启用作业控制(又名“监控模式”),以便我们可以使用前面问题中的简单解决方案之一:
接下来,我将简化您的大部分子shell 活动;你不需要它们。使用简化的命令,只是为了说明这一点:
您不必为所有终止进程启动整个子shell(并将其作为背景)。您不需要
sleep 10
在子shell 中运行。您实际上不需要测试 的返回代码sleep 10
来链接后续命令,使用&&
. 我已经修改了代码以匹配现有行为:如果 sleep 命令失败(例如,您按 Control-C),则脚本将退出并且不会启动后续的终止进程。最后,添加代码以终止子进程:
我改写了提示;您需要输入(几乎)任何键,然后按 ENTER 以便
read
命令看到您的输入,所以我只是建议用户按 ENTER。接下来,该read
命令接受一个变量名,但是REPLY
如果您不指定自己的变量名,它将使用一个名为的默认变量,因此取决于您是否更明显,这是简化代码的另一个选项。