Fixing “No such file or directory” Error When Running init.d Startup Script on Debian/Raspbian


2 views

When working with Debian-based systems like Raspbian, init.d scripts are a common way to manage services. The error you're seeing typically occurs when either:

  1. The file doesn't actually exist at the specified path
  2. There are hidden characters or encoding issues in the file
  3. Filesystem permissions are preventing execution
  4. The shebang line is incorrect

Before diving deeper, let's verify some basics:

# Check if file exists
ls -la /etc/init.d/testsam

# Verify file permissions
stat /etc/init.d/testsam

# Check file type and encoding
file /etc/init.d/testsam

# Attempt to read the file
cat -v /etc/init.d/testsam

Solution 1: Check for CRLF Line Endings

Windows-style line endings can cause this error. Convert them:

sudo sed -i 's/\r$//' /etc/init.d/testsam
sudo chmod +x /etc/init.d/testsam

Solution 2: Verify Shebang Line

The shebang must point to an existing interpreter:

#!/bin/bash
# or alternatively
#!/bin/sh

Verify bash location with:

which bash

Solution 3: Check File Encoding

Some text editors add BOM markers. Remove them:

sudo vi -c "set nobomb" -c "wq" /etc/init.d/testsam

If basic solutions don't work, try these:

# Check filesystem mount options
mount | grep " / "

# Verify inode exists
ls -i /etc/init.d/testsam
df -i /etc/init.d/

Here's an improved version of your script with better error handling:

#!/bin/bash
### BEGIN INIT INFO
# Provides:          testsam
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Test service
# Description:       Test service description
### END INIT INFO

case "$1" in
    start)
        echo "Starting service" >&2
        # Add your startup commands here
        ;;
    stop)
        echo "Stopping service" >&2
        # Add your shutdown commands here
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

Modern Debian systems often use systemd. Consider creating a systemd service instead:

[Unit]
Description=Test Service

[Service]
ExecStart=/path/to/your/script
User=root

[Install]
WantedBy=multi-user.target

Save as /etc/systemd/system/testsam.service then:

sudo systemctl daemon-reload
sudo systemctl enable testsam

After making changes, always:

sudo systemctl daemon-reload
sudo service testsam start
journalctl -xe  # Check logs for errors

Many developers encounter this frustrating error when setting up init scripts in Debian-based systems. The "No such file or directory" message can be misleading because it might appear even when the file exists. Let's break down the actual causes and solutions.

First, verify the file's actual presence and permissions:

ls -la /etc/init.d/testsam
file /etc/init.d/testsam

The error typically occurs in these scenarios:

  • Incorrect shebang line (space after #! matters)
  • File encoding issues (DOS vs UNIX line endings)
  • Missing interpreter (bash not installed)
  • Filesystem mount problems (rare but possible)

Try running these diagnostic commands:

# Check file type and encoding
file /etc/init.d/testsam

# Verify bash is available
which bash

# Check execute permissions
namei -l /etc/init.d/testsam

# Attempt direct execution
/bin/bash /etc/init.d/testsam start

For most cases, these solutions work:

# Ensure proper line endings
sudo apt-get install dos2unix
sudo dos2unix /etc/init.d/testsam

# Verify shebang line is exactly:
#!/bin/bash

# Reapply permissions (more secure)
sudo chmod 755 /etc/init.d/testsam
sudo chown root:root /etc/init.d/testsam

# Check dependencies
sudo apt-get install --reinstall bash

Modern Debian versions often use systemd. Here's equivalent implementation:

# /etc/systemd/system/testsam.service
[Unit]
Description=Test SAM Service

[Service]
Type=simple
ExecStart=/path/to/your/script.sh

[Install]
WantedBy=multi-user.target

Then enable with:

sudo systemctl daemon-reload
sudo systemctl enable testsam
sudo systemctl start testsam

Add these lines to your script for better debugging:

#!/bin/bash -x
exec > /tmp/testsam.log 2>&1
echo "Script started at $(date)"

This will create detailed execution logs in /tmp/testsam.log.