我正在尝试编写一个批处理脚本来创建新的终结器终端,然后在每个终端中运行一个进程。我希望他们继续在后台运行,直到我决定杀死他们。
我希望第一个进程运行 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 命令,但我认为在这种情况下它们与通用命令没有区别。我意识到代码非常混乱,如果您发现任何其他问题,我很高兴听到。谢谢!
答案1
当以非交互方式运行时(例如在脚本中),bash 会禁用作业控制,因此可以使用简单的方法来终止后台进程,例如杀死所有后台作业或者如何杀死 bash 中的所有作业?默认情况下不起作用。
我要做的第一件事就是通过将 sh-bang 行更改为以下内容来确保您正在运行 bash:
#!/bin/bash
接下来,让我们启用作业控制(又名“监控模式”)这样我们就可以使用前面问题中的简单解决方案之一:
set -m
接下来,我将简化您的大部分子 shell 活动;你不需要它们。使用简化的命令,只是为了演示这一点:
#wait 10 seconds before starting nav and rviz otherwise will get error
sleep 10 || exit
terminator -T "navigation ... bash" &
terminator -T "rviz ... bash" &
...
terminator -T "spawn_objects_launch" &
echo Press any key to to shutdown all processes
read varname
echo Shutting down...
您不必为所有终止程序进程启动整个子 shell(并将其置于后台)。您不需要sleep 10
在子 shell 中运行。你不真的需要测试 的返回码sleep 10
以便链接后续命令,用&&
.我已经调整了代码以匹配现有的行为:如果 sleep 命令失败(例如,您按下 Control-C),则脚本将退出并且不会启动后续的终止程序进程。
最后,添加杀死子进程的代码:
...
terminator -T "spawn_objects_launch" &
echo Press ENTER to shutdown all processes
read
echo Shutting down...
kill $(jobs -p)
我重新表述了提示;您需要输入(几乎)任意键,然后按 ENTER 键才能让命令read
看到您的输入,因此我只是建议用户按 ENTER 键。接下来,该read
命令接受一个变量名称,但是如果您不指定自己的变量名称,它将使用一个名为 name 的默认变量REPLY
,因此根据这对您来说是否更明显,这是简化代码的另一个选项。