Почему я получаю «строка 1: $ ': \ r': command not found"?

Я использовал Cygwin на своем ноутбуке (DOS). У меня есть набор сценариев от моих коллег и мой собственный. Я не ИТ-специалист, не знающий в Unx. Я следую синтаксису моих коллег и умею управлять несколькими простыми вещами.

Сценарии хорошо работали на моем старом ноутбуке. Я просто сменил ноутбук, установил Cygwin. Когда я запускаю свои скрипты, они не работают. Вот один из примеров сообщения об ошибке:

line 1: $':\r': command not found line 5: syntax error near unexpected token `$'\r'' line 5: `fi 

Вот первые 5 строк моего скрипта

 : iter=1 if [ -f iter.txt ] then rm ./iter.txt fi 

Может кто-нибудь объяснить, как я могу обойти эту проблему?

4 Solutions collect form web for “Почему я получаю «строка 1: $ ': \ r': command not found"?”

У вас завершены строки в стиле Windows.

Команда no-op : вместо этого считывается как :<carriage return> , отображаемый как :\r или более полностью как $':\r' .

Запустите dos2unix scriptname и все будет хорошо.


Если у вас нет dos2unix , следующее должно работать практически в любом месте (и я тестировал MobaXterm в Windows):

 vi -b filename 

Затем в vi введите:

 :%s/\r$// :x 

Тебе хорошо идти.


В vim , который вы используете для Cygwin для vi , есть несколько способов сделать это. Другой fileformat включает в fileformat параметр fileformat , который может принимать значения dos или unix . Либо явным образом изменим его после загрузки файла с помощью

  set fileformat = unix 

или явно форматировать формат файла при записи файла с помощью

  : w + fileformat = unix 

Подробнее об этом см. В многочисленных вопросах и ответах, охватывающих этот вопрос, в том числе:

  • Удалить символ ^ M из файлов журнала
  • Почему vim создает файлы с окончанием строки DOS?
  • Как добавить возврат каретки перед каждой новой линией?

Это связано с тем, что сценарий был сохранен редактором, который использует DOS-строки (например, Notepad ++, например). Вам придется удалить их из своих сценариев.

Для этого либо используйте dos2unix в файле сценария, либо

 $ tr -d '\r' <script >script.new && mv script.new script 

(это приведет к удалению всех возвратов каретки из любого места в скрипте)


Что касается кода в скрипте:

 : iter=1 if [ -f iter.txt ] then rm ./iter.txt fi 

Это должно выглядеть примерно так:

 iter=1 if [ -f "./$iter.txt" ]; then rm "./$iter.txt" fi 

Это удаляет файл 1.txt из текущего каталога, если он существует. Команда : ничего не делает (почти) и может быть удалена. Значение переменной iter следует использовать как $iter и указывать. И тогда я могу быть более явным, чем нужно, используя ./ чтобы сказать, что файл нужно найти в текущем каталоге.

Если вы планируете превратить это в цикл (здесь, удалив все файлы 1.txt , 2.txt , …, 10.txt ):

 iter=1 while [ "$iter" -le 10 ]; then if [ -f "./$iter.txt" ]; then rm "./$iter.txt" fi iter=$(( iter + 1 )) done 

Или, если мы чувствуем подлый / ленивый,

 rm -f {1..10}.txt 

в оболочках, которые понимают расширение скобки.

У ваших сценариев неправильные окончания строк. Windows использует CR + LF (\ r \ n), Unix использует LF (\ n), а Classic MacOS использует CR (\ r). Вам нужно будет изменить концы строк во всех затронутых файлах либо текстовым редактором, либо автономным инструментом, например dos2unix .

Системы управления FTP и версиями, такие как SVN, как правило, имеют возможность правильно конвертировать концы строк, поэтому вы можете захотеть просмотреть эти параметры для передачи файлов в будущем.

Если эти файлы не передаются, а просто используются на одной машине, вам нужно найти настройки для окончаний строк в предпочитаемом текстовом редакторе. Большинство, которые рекламируются как «для программистов», будут иметь такой вариант.

В качестве дополнительного ответа позвольте мне добавить пару примечаний / советов …

Во-первых, для обычных текстовых файлов вы можете легко определить, заканчивается ли в них строка Unix или DOS с помощью команды file . Например:

 $ file test.txt test.txt: ASCII text, with CRLF line terminators $ dos2unix test.txt dos2unix: converting file test.txt to Unix format... $ file test.txt test.txt: ASCII text 

Обратите внимание на мое использование dos2unix . Я настоятельно рекомендую вам установить его. В зависимости от того, как вы используете Cygwin, вы можете обнаружить, что вам нужно сделать это преобразование достаточно часто, чтобы это было удобно. Что еще более важно, нет никаких шансов на ошибку, как вы можете получить с помощью ручных изменений, обсуждаемых здесь.

Чтобы установить запуск основного исполняемого файла Cygwin. Это тот, у кого есть имя, например setup-x86_64.exe или что-то в этом роде. Убедитесь, что вы видите такой экран:

введите описание изображения здесь

Поскольку вы уже сделали основную установку, вы должны будете нажать « Далее» до тех пор, пока не получите экран выбора. В раскрывающемся списке выберите «Полный» и введите «dos2» в поле поиска и выберите инструмент, как показано здесь:

введите описание изображения здесь

Затем нажмите « Далее» и завершите установку. Вот и все. Повеселись. Cygwin, за исключением этого случайного неудобства, является удивительным пакетом.

  • проверьте два раздела, выбрав случайные файлы и запустив хэши sha1 по двум файлам каждого раздела
  • zsh: исключение файлов из шаблона
  • Удаление разделов каталога для получения имен файлов
  • Сравнить строки и обновить два разных файла
  • Как искать и заменять текст во всех php-файлах в каталоге и в его подкаталогах
  • команды curl и grep выводятся в новую переменную
  • Bash Scripting: автоматизировать команду в консоли
  • sed Удалить строки, заканчивающиеся на %
  • Как разобрать этот вывод и поместить его в массив?
  • Команда mv для перемещения и переименования набора файлов
  • Скрипт, который выводит общее количество строк во всех текстовых файлах, передаваемых в качестве аргументов
  • Linux и Unix - лучшая ОС в мире.