Por que estou recebendo “linha 1: $ ': \ r': comando não encontrado”?

6

Eu usei o Cygwin no meu laptop (DOS). Eu tenho uma coleção de scripts dos meus colegas e dos meus. Eu não sou uma pessoa de TI, não tenho conhecimento em Unix. Eu sigo a sintaxe dos meus colegas e sou capaz de gerenciar algumas coisas simples.

Os scripts funcionaram bem no meu laptop antigo. Acabei de mudar de laptop, instalei o Cygwin. Quando eu executo meus scripts, eles não funcionam. Aqui está um exemplo da mensagem de erro:

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

Aqui estão as 5 principais linhas do meu script

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

Alguém por favor pode explicar como posso contornar este problema?

    
por TPham 09.09.2017 / 00:12

6 respostas

16

Você tem finais de linha no estilo do Windows.

O comando no-op : é lido como :<carriage return> , exibido como :\r ou mais como $':\r' .

Execute dos2unix scriptname e você deve estar bem.

Se você não tem dos2unix , o seguinte deve funcionar quase em qualquer lugar (e testei no MobaXterm no Windows):

vi -b filename

Em seguida, em vi , digite:

:%s/\r$//
:x

Você é bom para ir.

Em vim , que é o que você está usando no Cygwin para vi , existem várias maneiras de fazer isso. Outra envolve a configuração fileformat , que pode receber os valores dos ou unix . Altere explicitamente depois de carregar o arquivo com

set fileformat=unix
ou forçar explicitamente o formato do arquivo ao gravar o arquivo com
:w +fileformat=unix

Para saber mais sobre isso, veja as muitas perguntas e respostas sobre esse assunto, incluindo:

por 09.09.2017 / 00:20
8

Isso ocorre porque o script foi salvo por um editor que usa finais de linha do DOS (como o Notepad ++, por exemplo). Você terá que removê-los dos seus scripts.

Para fazer isso, use dos2unix no arquivo de script ou

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

(isso removerá todos os retornos de carro de em qualquer lugar no script)

Quanto ao código no script:

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

Isso deve parecer algo como

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

Isso remove o arquivo 1.txt do diretório atual, se existir. O comando : não faz nada (quase) e pode ser removido. O valor da variável iter deve ser usado como $iter e ser citado. E, possivelmente, estou sendo mais explícito do que o necessário usando ./ para dizer que o arquivo precisa ser encontrado no diretório atual.

Se você planeja transformar isso em um loop (aqui, excluindo todos os arquivos 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

Ou, se nos sentirmos sorrateiros / preguiçosos,

rm -f {1..10}.txt

em shells que entendem de expansão de chaveta.

    
por 09.09.2017 / 00:20
5

Seus scripts têm finais de linha incorretos. O Windows usa CR + LF (\ r \ n), o Unix usa LF (\ n) e o MacOS clássico usa CR (\ r). Você precisará alterar os fins de linha em todos os arquivos afetados, seja com um editor de texto ou uma ferramenta autônoma, como dos2unix .

Os sistemas de controle de versão e FTP, como o SVN, tendem a converter os terminais de linha apropriadamente, portanto, convém examinar essas opções para transferir arquivos no futuro.

Se esses arquivos não estiverem sendo transferidos, mas usados em uma única máquina, você precisará encontrar as configurações para finais de linha em seu editor de texto preferido. A maioria dos que são anunciados como "para programadores" terão essa opção.

    
por 09.09.2017 / 00:21
3

Como resposta suplementar, deixe-me adicionar algumas notas / dicas ...

Primeiro, para arquivos de texto regulares, você pode facilmente determinar se eles têm linha Unix ou DOS terminando usando o comando file . Por exemplo:

$ 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

Observe meu uso de dos2unix . Eu recomendo que você o instale. Dependendo de como você usa o Cygwin, você pode achar que precisa fazer essa conversão com frequência suficiente para que a conveniência seja bem-vinda. Mais importante, não há chance de erro, como acontece com as edições manuais discutidas aqui.

Para instalar, inicie o executável principal do Cygwin. Esse é o único com o nome como setup-x86_64.exe ou algo nesse sentido. Certifique-se de ver uma tela como esta:

Comovocêjáfezainstalaçãoprimária,vocêdeveclicarPróximoatéchegarnateladeseleção.SelecioneCompletanalistasuspensaedigite"dos2" na caixa de pesquisa e escolha a ferramenta conforme mostrado aqui:

Em seguida, clique em Próximo novamente e deixe a instalação completa. É isso aí. Diverta-se. O Cygwin, com exceção desse inconveniente ocasional, é um pacote incrível.

    
por 09.09.2017 / 06:46
1

Se não for dos2unix, há também 'flip'

$ flip -u yourfilename.txt

irá invertê-lo para usar finais de linha unix.

    
por 05.09.2018 / 11:02
1

Eu uso Notepad ++ para editar meus scripts bash (.sh) conectando ao servidor por WinSCP
(Para configurar o editor do WinSCP para o Notepad ++: link )

Isso é muito prático para abrir arquivos de servidores para editar / salvar em vez de editor " Vim ".
Quando você abrir o arquivo no Notepad ++ , clique duas vezes na 7ª coluna na barra de status na parte inferior e selecione " Unix (LF) ".

Além disso, você precisa alterar o 8º por Codificação - > Codifique em UTF-8 na barra superior.

    
por 04.09.2018 / 19:16