如何让Shell脚本开机自动运行?脚本终端正常但开机失效求助
Let's work through why your boot.sh runs perfectly when you execute it manually in the terminal, but fails to start up when configured via /etc/rc.local. First, here's your script for reference:
#!/bin/bash cd /home/icrs/manipulator_proj source devel/setup.bash xterm -hold -e "roscore" & //xterm -hold -e "cd ~/manipulator_proj/ && ls && catkin_make" //xterm -hold -e "cd ~/manipulator_proj/ && source devel/setup.bash" xterm -hold -e "cd ~/manipulator_proj/ && rosrun dynamixel_control dynamixel_control" xterm -hold -e "cd ~/manipulator_proj/ && rosrun dynamixel_control ik" xterm -hold -e "cd ~/manipulator_proj/ && rosrun dynamixel_control server_node"
Below are the key issues causing the startup failure, along with actionable fixes:
1. rc.local Runs Without User Environment & X Display
When /etc/rc.local executes during boot, it runs as the root user—not your icrs account. This means:
- It doesn’t load your user-specific ROS environment variables.
- The X server (required for
xtermto launch) hasn’t started yet.
Fix:
Run the script as your icrs user and explicitly set the display. Update your /etc/rc.local entry to:
su - icrs -c "export DISPLAY=:0 && /home/icrs/boot.sh" &
The - flag ensures your full user environment is loaded, and DISPLAY=:0 targets your primary display (adjust to :1 if you use multiple monitors).
2. Relative Paths (~) Break in rc.local
When running as root, ~/ points to /root, not /home/icrs. The ~/manipulator_proj paths in your script will fail because that directory doesn’t exist under root’s home.
Fix:
Replace all instances of ~/manipulator_proj with the absolute path /home/icrs/manipulator_proj in your boot.sh.
3. ROS Nodes Start Before roscore is Ready
You background roscore with &, but the subsequent xterm commands launch immediately. ROS nodes need roscore to be fully initialized before they can connect.
Fix:
Add a sleep delay after starting roscore to give it time to spin up. Modify that line in boot.sh:
xterm -hold -e "roscore" & sleep 10 # Adjust this value if needed (5-15 seconds usually works)
4. rc.local Executes Too Early (Before X Server Starts)
Even with the DISPLAY set, rc.local often runs before the X server is fully ready, causing xterm to fail. For desktop systems, running the script after user login is more reliable.
Alternative Fix:
Instead of rc.local, add your script to your user’s startup applications:
- For GNOME: Open "Startup Applications" → Add → Point to
/home/icrs/boot.sh. - For other DEs: Use their built-in startup manager, or add the command to your
~/.bashrc(wrap it in a check to only run once per login to avoid duplicates).
Modified boot.sh Example
Here’s your script with path fixes and the sleep delay added:
#!/bin/bash cd /home/icrs/manipulator_proj source devel/setup.bash xterm -hold -e "roscore" & sleep 10 # xterm -hold -e "cd /home/icrs/manipulator_proj/ && ls && catkin_make" # xterm -hold -e "cd /home/icrs/manipulator_proj/ && source devel/setup.bash" xterm -hold -e "cd /home/icrs/manipulator_proj/ && rosrun dynamixel_control dynamixel_control" xterm -hold -e "cd /home/icrs/manipulator_proj/ && rosrun dynamixel_control ik" xterm -hold -e "cd /home/icrs/manipulator_proj/ && rosrun dynamixel_control server_node"
Don’t forget to ensure the script is executable:
chmod +x /home/icrs/boot.sh
内容的提问来源于stack exchange,提问作者arun kumar marri

