# Convert line endings with dos2unix

Windows uses `CRLF` (`\r\n`) line endings; Linux uses `LF` (`\n`). When a `.sh` script makes the trip from a Windows editor to a Pi-class device, bash sees the carriage return as part of the shebang — `#!/bin/bash\r` — and refuses to run the script. The error you'll see is misleading:

```text
-bash: ./your_script.sh: /bin/bash^M: bad interpreter: No such file or directory
```

It looks like the interpreter is missing. It isn't — the line endings are wrong. `dos2unix` strips the `\r` and the script runs.

This bites you almost every time you copy a script from a Windows machine to the FR201 over a USB stick or via SCP.

## Install dos2unix

```sh title="Install on Raspberry Pi OS"
sudo apt-get install dos2unix -y
```

## Convert a single script

```sh title="Convert and run a script"
dos2unix your_script.sh
sudo chmod +x your_script.sh
./your_script.sh
```

## Convert many files at once

If you've just copied a directory of scripts onto the device, use `find` to convert in bulk.

Convert every file in the current directory (non-recursive):

```sh title="Convert files in this directory"
find . -maxdepth 1 -type f -exec dos2unix {} \;
```

Convert only shell scripts, recursively:

```sh title="Convert all .sh files recursively"
find . -type f -name "*.sh" -exec dos2unix {} \;
```

Convert every file under the current tree:

```sh title="Convert everything (use with care)"
find . -type f -exec dos2unix {} \;
```

Then make the shell scripts executable in one pass:

```sh title="Mark scripts executable"
find . -type f -name "*.sh" -exec chmod +x {} \;
```

## Automate the USB-drive copy

If you're constantly hand-carrying scripts on a USB stick, automate the convert-and-copy step. The script below mounts a USB drive, converts every file from CRLF to LF, copies the tree to a destination directory, and marks the shell scripts executable.

See the [Mount a USB drive](/guides/onlogic-fr201/mount-usb/) guide for how to set up the mount point.

1. Create the helper script in your home directory:

    ```sh title="Create the helper script"
    sudo nano /home/pi/convert-files-on-copy.sh
    ```

2. Paste in the contents below. Adjust `USB_MOUNT` and `DEST` to match your setup:

    ```sh title="/home/pi/convert-files-on-copy.sh"
    #!/bin/bash
    # Converts CRLF to LF on every file on a mounted USB drive,
    # copies the tree to DEST, and marks shell scripts executable.

    USB_MOUNT="/media/usbdrive"
    DEST="/home/pi/scripts"

    if ! mountpoint -q "$USB_MOUNT"; then
        echo "USB drive not mounted at $USB_MOUNT. Mount it first."
        exit 1
    fi

    echo "Converting files from Windows format..."
    find "$USB_MOUNT" -type f -exec dos2unix {} \;

    echo "Copying files to $DEST..."
    mkdir -p "$DEST"
    cp -r "$USB_MOUNT"/* "$DEST"/

    echo "Marking shell scripts executable..."
    find "$DEST" -type f -name "*.sh" -exec chmod +x {} \;

    echo "Done."
    ```

3. Make it executable:

    ```sh title="Mark the helper executable"
    sudo chmod +x /home/pi/convert-files-on-copy.sh
    ```

4. Run it whenever you've plugged in a fresh USB stick:

    ```sh title="Run the helper"
    /home/pi/convert-files-on-copy.sh
    ```

:::tip[Avoid the problem entirely]
If you control the source machine, configure your editor (VS Code, Notepad++, Sublime, etc.) to save files with LF line endings. In VS Code, set `"files.eol": "\n"` in `settings.json`. A `.gitattributes` file with `*.sh text eol=lf` enforces it for anything checked into Git.
:::