¿Por qué recibo "línea 1: $ ': \ r': comando no encontrado"?

13

Usé Cygwin en mi computadora portátil (DOS). Tengo una colección de guiones de mis colegas y la mía. No soy una persona de TI, no estoy bien informado en Unix. Sigo la sintaxis de mis colegas y puedo administrar algunas cosas simples.

Los guiones funcionaron bien en mi vieja computadora portátil. Acabo de cambiar la computadora portátil, instalé Cygwin. Cuando ejecuto mis scripts, no funcionan. Aquí hay un ejemplo del mensaje de error que recibo:

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

Aquí están las 5 primeras líneas de mi script

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

¿Puede alguien explicarme cómo puedo solucionar este problema?

TPham
fuente

Respuestas:

28

Tiene finales de línea estilo Windows.

El comando no-op :se lee como :<carriage return>, se muestra como :\ro más completamente como $':\r'.

Corre dos2unix scriptnamey deberías estar bien.


Si no tiene dos2unix, lo siguiente debería funcionar en casi cualquier lugar (y probé en MobaXterm en Windows):

vi -b filename

Luego en vi, escriba:

:%s/\r$//
:x

Eres bueno para ir.


En vim, que es lo que está utilizando en Cygwin vi, hay varias formas de hacerlo. Otro involucra la fileformatconfiguración, que puede tomar los valores doso unix. Cambie explícitamente después de cargar el archivo con

set fileformat = unix
o forzar explícitamente el formato de archivo al escribir el archivo con

: w + fileformat = unix

Para obtener más información sobre esto, consulte las numerosas preguntas y respuestas aquí que cubren este tema, que incluyen:

Comodín
fuente
Solo quiero aclarar, "iter = 1" es mi contador que se usará para la cantidad de rondas de un algoritmo matemático que mi modelo tendrá que repetir más adelante en la línea 5. Acabo de publicar las 5 líneas principales para ir con el mensaje de error. ¡Todos los comentarios e instrucciones son muy apreciados!
TPham
Acabo de probar el comando sugerido "$ tr -d ....." pero hay algo mal con mi computadora portátil. No vuelve a "$" pero en su lugar aparece ">" en la pantalla. Tengo que usar contrl C para salir. Luego, probé el script para ver si el problema está solucionado, pero todavía está allí. Lo siento, mi conocimiento en este campo es muy mínimo. Estoy tratando de utilizar mi colección de scripts, ya que ayudan mucho a mi trabajo. Gracias a todos por ser pacientes y útiles para mí.
TPham
@TPham, ver edición. Si esto funciona, asegúrese de utilizar la marca de verificación junto a la respuesta para "aceptarlo". (Acepte la respuesta que mejor resuelva su problema.) Unix.stackexchange.com/help/someone-answers
Comodín el
1
Los comandos que son palabras no son realmente más complicados para un novato que un encantamiento misterioso que es casi totalmente un signo de puntuación. Esto no necesita una respuesta por separado. Simplemente necesita esta respuesta para mencionar que vimpuede hacer esto de dos maneras, una de las cuales usa palabras. O, mejor aún, señalar dónde se ha respondido esta tarea subordinada una y otra vez con mucho más detalle que cualquier respuesta en esta página, incluido unix.stackexchange.com/questions/88811 solo para empezar.
JdeBP
1
Tenga en cuenta que vi -b, de \rtodos modos , son extensiones vim. no POSIX, no en nvi, elvis, Solaris vi ...
Stéphane Chazelas
10

Esto se debe a que el guión ha sido guardado por un editor que utiliza finales de línea de DOS (como Notepad ++, por ejemplo). Deberá eliminarlos de sus scripts.

Para hacer esto, use dos2unixen el archivo de script o

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

(esto eliminará todos los retornos de carro de cualquier parte del script)


En cuanto al código en el script:

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

Esto posiblemente debería parecerse a algo como

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

Esto elimina el archivo 1.txtdel directorio actual, si existe. El :comando no hace nada (casi) y puede eliminarse. El itervalor de la variable debe usarse como $iter, y ser citado. Y luego posiblemente estoy siendo más explícito de lo que necesito ./al decir que el archivo debe encontrarse en el directorio actual.

Si usted está planeando convertir esto en un bucle (en este caso, la supresión de todos los archivos 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

O, si nos sentimos furtivos / flojos,

rm -f {1..10}.txt

en conchas que entienden la expansión de los aparatos.

Kusalananda
fuente
3
Notepad ++ en realidad tiene la opción de usar saltos de línea de Windows / Mac / Linux. Solo necesita ir al menú Editar y luego Conversión EOL-> Unix (LF). O simplemente puede hacer doble clic en la esquina inferior derecha donde dice Windows (CR LF)y cambiarlo aUnix (LF)
jesse_b
Gracias a todos por su instrucción. Quisiera aclarar: el "iter = 1" es un contador que uso más adelante para mi objetivo principal, más allá de la línea 5.
TPham
@TPham De nada. Estaba aburrido, tomé tu código y dejé que mi mente se volviera impresionista.
Kusalananda
O rm -f [1-9].txt 10.txt. Pero eso no es totalmente equivalente lógicamente, como si no hay archivos de 1-9, pero no es un archivo llamado literalmente [1-9].txta continuación, se eliminará. : D
Comodín
5

Sus guiones tienen los finales de línea incorrectos. Windows usa CR + LF (\ r \ n), Unix usa LF (\ n) y Classic MacOS usa CR (\ r). Tendrá que cambiar los finales de línea en todos los archivos afectados, ya sea con un editor de texto o una herramienta independiente como dos2unix.

Los sistemas de control de versiones y FTP como SVN tienden a ser capaces de convertir las terminaciones de línea de manera apropiada, por lo que es posible que desee examinar esas opciones para transferir archivos en el futuro.

Si estos archivos no se transfieren, sino que solo se usan en una sola máquina, entonces querrá encontrar la configuración para los finales de línea en su editor de texto preferido. La mayoría de los anunciados como "para programadores" tendrán esa opción.

zorro
fuente
Gracias a todos por sus útiles instrucciones. Acabo de probar dos2unix pero parece que no lo tengo. Buscará e intentará nuevamente.
TPham
3

Como respuesta complementaria, permítanme agregar un par de notas / consejos ...

Primero, para los archivos de texto normales, puede determinar fácilmente si tienen un final de línea Unix o DOS utilizando el filecomando. Por ejemplo:

$ 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

Tenga en cuenta mi uso de dos2unix. Le recomiendo que lo instale. Dependiendo de cómo use Cygwin, es posible que necesite hacer esta conversión con la frecuencia suficiente para que la conveniencia sea bienvenida. Más importante aún, no hay posibilidad de error como el que obtiene con las ediciones manuales discutidas aquí.

Para instalar, inicie el ejecutable principal de Cygwin. Ese es el que tiene el nombre como setup-x86_64.exe o algo por el estilo. Asegúrese de ver una pantalla como esta:

ingrese la descripción de la imagen aquí

Como ya ha realizado la instalación principal, debería poder hacer clic en Siguiente hasta que aparezca la pantalla de selección. Seleccione Completo en el menú desplegable e ingrese "dos2" en el cuadro de búsqueda y elija la herramienta como se muestra aquí:

ingrese la descripción de la imagen aquí

Luego haga clic en Siguiente nuevamente y deje que se complete la instalación. Eso es. Que te diviertas. Cygwin, con la excepción de este inconveniente ocasional, es un paquete increíble.

Capa B
fuente
Muchas gracias por tu instrucción B Layer! Este grupo de Stack Exchange es muy útil. Realmente aprecio este apoyo.
TPham
1

Si no es dos2unix, también hay 'flip'

$ flip -u yourfilename.txt

lo cambiará a usar terminaciones de línea unix.

chai
fuente
1

Utilizo Notepad ++ para editar mis scripts bash (.sh) conectándome al servidor mediante WinSCP
(para configurar el editor WinSCP en Notepad ++: https://winscp.net/eng/docs/ui_editor_preferences )

Esto es muy práctico para abrir archivos de servidores para editar / guardar en lugar del editor " Vim ".
Cuando abra el archivo en Notepad ++ , haga doble clic en la séptima columna en la barra de estado en la parte inferior y seleccione " Unix (LF) ".

ingrese la descripción de la imagen aquí

Además, debe cambiar el octavo codificando -> Codificar en UTF-8 en la barra superior.

Alper t. Turker
fuente
0

No necesita cambiar la codificación de línea del archivo real para que Cygwin's Bash funcione felizmente con las codificaciones de fin de línea de Mac y Windows. Hay una opción que solo necesitas activar.

Simplemente actualice su ~/.bash_profilepara que contenga

export SHELLOPTS
set -o igncr

Ver https://ptolemy.berkeley.edu/projects/chess/softdevel/faq/5.html

swdev
fuente