Bash файл возвращает неожиданный токен `$ 'do\r' '

Я нашел этот script онлайн и попытался использовать его:

#!/bin/sh
# Target directory
TARGET=$3
echo "Copying to $TARGET"
for i in $(git diff --name-only $1 $2)
    do
        # First create the target directory, if it doesn't exist.
        mkdir -p "$TARGET/$(dirname $i)"
        # Then copy over the file.
        cp "$i" "$TARGET/$i"
    done
echo "Done";

Я проверил script онлайн, а script в порядке. Я также пытался изменить его по-разному, но это не работает для меня.

Я также пытался запустить что-то вроде:

#!/bin/sh
# Target directory
TARGET=$3
echo "Copying to $TARGET"
for i in $(ls)
do
    echo "text"
done

И я все равно получаю ту же ошибку:

./git-copy.sh: line 6: syntax error near unexpected token `$'do\r''
'/git-copy.sh: line 6: `do

Почему это?

Ответ 1

Ваш script был отредактирован в системе DOS или Windows и содержит символы возврата каретки, которые Linux/Unix не нравится (что означает \r). Вы можете использовать dos2unix для преобразования окончаний строки возврата каретки в правильный формат; если у вас нет dos2unix, вы можете использовать awk как

awk '{ sub("\r$", ""); print }' git-copy.sh > git-copy2.sh
mv git-copy2.sh git-copy.sh

Ответ 2

Другое возможное решение с использованием текстового редактора unix vi:

открыть файл в редакторе vi с помощью команды vi filename.sh;

введите команду vi :set ff=unix;

сохранить файл с помощью :wq

Он сохранит файл с окончанием строки unix.

Ответ 3

Это сработало для меня:

dos2unix my_script.sh

Если у вас нет dos2unix:

Для CentOS, Fedora или RHEL:

$ sudo yum install dos2unix

Для Ubuntu или Debian:

$ sudo apt-get install tofrodos
$ sudo ln -s /usr/bin/fromdos /usr/bin/dos2unix 

Объяснение

Обычно это происходит, когда исполняемый файл создается в операционной системе (Windows) и используется в другой операционной системе (Linux). Также редкие текстовые редакторы могут быть проблемой.

Ответ 4

Это довольно распространенный кошмар:)

Я построил script для нормализации \r\n из Dos и из (старого) Mac; он также удаляет спецификацию если присутствует:

#!/usr/bin/perl -pi
s/\012\r|\r\012|\012|\r/\012/g;            ## normalize line endings
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//;     ## remove common initial BOM

Использование: script textualfile*

Хорошо, хорошо: выберите лучшее имя для этого! chmod и установить его

Ответ 5

Просто измените последовательность строк в текстовом редакторе с CRLF на LF. У меня это сработало :)

для notepad++: edit => EOL Conversion => Unix(LF)

Ответ 6

У меня был случай, когда мне нужно было записать (INSERT) в БД поле, в котором был такой сценарий bash (в версии Intellij Idea для Windows), а затем мне пришлось считывать сценарий из БД обратно на сервер Unix. В Unix я получил эту тему ошибки $'do\r'' по причине, описанной выше.

Решение было - скопировать\вставить скрипт на Win в Блокнот, изменить в конце Unix строки Блокнота с Windows (CR LF) на Unix (LF), сохранить его в файл. Откройте файл, скопируйте\вставьте в консоль базы данных Idea. Тогда он работал нормально на Unix для случая, когда он не был из Unix.

(У идеи также есть варианты выбора концов строк в редакторе)