2011-11-29 17 views
5

Tengo un problema con un personaje. Creo que es un problema de conversión entre DOS y Unix.Programación Bash (Cygwin): carácter ilegal^M

Tengo una variable que es un valor flotante. Al imprimir con el comando echo me sale:

0.495959 

Pero cuando trato de hacer una operación en ese valor con el comando antes de Cristo (no estoy seguro de cómo escribir el comando antes de Cristo).

echo $mean *1000 |bc 

me sale:

(standard_in) 1 : illegal character: ^M 

ya que utiliza el comando dos2unix en mi archivo .sh. Creo que es porque mi variable tiene el carácter^M (no impreso con el comando echo)

¿Cómo puedo eliminar este error?

+0

¿Cómo se obtiene '$ mean'? – netcoder

+0

Usando el comando "identificar" de ImageMagick. Pero como estoy en Windows, tal vez da su resultado en formato DOS y no en formato Unix. ¿Qué causa que se agregue un carácter de carro? – Frencoo

+0

Está bien, pero ¿cuál es el comando que está ejecutando para que '$ mean' se rellene? Algo como 'mean = \' identify ... \ '' ... necesitamos la línea completa. – netcoder

Respuesta

11

no tengo Cygwin a mano, pero en Bash regulares, puede utilizar el comando tr -d que se deben eliminar caracteres específicos, y se puede utilizar la notación $'...' para especificar caracteres extraños en un argumento de línea de comandos (que es como una cadena normal entre comillas simples, excepto que admite secuencias de escape C/Java/Perl/etc., como las secuencias de escape). Por lo tanto, la siguiente:

echo "$mean" * 1000 | tr -d $'\r' | bc 

eliminará los retornos de carro en el camino de echo a bc.

En realidad, puede que desee ejecutar esto:

mean=$(echo "$mean" | tr -d $'\r') 

que modificará $mean que se deben eliminar los retornos de carro en el interior, y luego usted no tendrá que preocuparse de que en los comandos posteriores que lo utilizan.

(Aunque también vale la pena echar un vistazo al código que establece $mean para empezar. ¿Cómo funciona $mean llegar a tener un retorno de carro en el mismo, de todos modos? Tal vez se puede arreglar eso.)

+0

¡Eso es mucho hombre, funciona! – Frencoo

1

Tal vez debería guardar su script en formato UNIX en lugar de DOS.

+0

Ya uso el comando dos2unix para convertirlo. ¿Es lo que quieres decir? – Frencoo

+0

Sí, lo es. No sé por qué usar dos2unix no resolvió su problema. El código se ve bien para mí. Lo intenté y funciona bien. Pero, si guardo el script en modo dos, obtengo el mismo error: '(standard_in) 1: carácter ilegal:^M'. Por lo general, no uso dos2unix, solo porque estoy más cómodo con un editor. Para replicar tu código, utilicé [pspad] (http://www.pspad.com). Es gratis, tal vez podrías intentarlo. – loscuropresagio

+0

Gracias intentaré con el pspad – Frencoo

0

Prueba esto:

echo `echo $mean` *1000 |bc 

Si eco realmente no está imprimiendo, debería funcionar.

+2

Es una buena idea, pero no ayudará. Si '$ mean' contiene'^M', y Bash reconoce '^ M' como un separador de palabras (que, por defecto, lo hace * not *), entonces' echo $ mean * 1000' ya soltará el '^ M ', porque' $ mean' no está citado. Si * es * 'echo' que está agregando'^M', obviamente no funcionará (como te habrás dado cuenta), y si '^ M' está en la variable y Bash * no está * reconociendo como un separador de palabras, entonces el 'eco' interno todavía imprimirá el'^M' y el 'eco' externo lo repetirá - nada ganado. – ruakh

+0

@ruakh ¡Tienes razón, no lo había pensado bien! – elias

0

^M es un carácter carriage return que se utiliza en Windows junto con el carácter de nueva línea (\n) para indicar la siguiente línea. Sin embargo, no es así como se hace en el mundo UNIX, por lo que bash no trata como un carácter especial y rompe la sintaxis. Lo que debes hacer es eliminar ese personaje usando uno de muchos métodos. La herramienta dos2unix puede ser útil, por ejemplo.

+0

Como mencioné, ya usé el comando dos2unix en mis archivos .sh. ¿Es eso lo que quieres decir o debo usar de otra manera? – Frencoo

2

Estos trabajos :

${mean/^M/}

Puede obtener^M al presionar Ctrl-V seguido de Ctrl-M.O, alternativamente:

${mean/$(printf "\r")/}

La ventaja de este método en comparación con @ruakh 's es que sólo aquí se está utilizando bash empotrados. El primero será más rápido ya que el segundo se ejecutará dentro de una subshell.

Si lo que desea es "unixize" $ media:

mean="${mean/^M/}"

Editar: Hay otro manera:

${mean/$'\r'/}

0

Como otros han señalado, esto es un Windows finalización de línea. Hay muchas maneras de solucionar el problema, pero la pregunta es por qué sucedió esto en primer lugar.

puedo ver que esto ocurra en varios lugares:

  • Ésta es una variable de entorno de Windows que se establece cuando se puso en marcha Cygwin. A veces estas variables obtienen un CRLF al final de ellas. Mencionó que este era un problema particular con esta variable, pero no especificó dónde se configuró.

  • Tras editar este archivo con un editor de texto de Windows como el Bloc de notas o WinPad.

Nunca utilice un texto editor de para editar un programa. Use un editor de programa. Si te gusta VI, descarga VIM que está disponible en Windows y viene en Cygwin (y todas las demás plataformas basadas en Unix). Si VIM no es para ti, prueba el Notepad++ basado más gráficamente. Ambos editores manejan problemas de final de línea y pueden crear scripts con terminaciones de línea Unix en Windows o archivos con terminaciones de línea de Windows en Cygwin.


  • Si utiliza VIM, puede hacer lo siguiente para cambiar los finales de línea y de introducirlos:

    • para ver el final de línea en el archivo actual, tipo :set ff? mientras que en el comando modo.
    • Para establecer el final de línea para Unix, escriba :set ff=unix mientras está en modo comando.
    • Para establecer el final de línea para Windows, escriba :set ff=dos mientras está en modo comando.
  • Si utiliza Notepad ++

    • Puede entrar en el Editar -> Conversión EOL elemento de menú y ver lo que su línea actual configuración final (que es la que no resaltado) y cambiarlo .
    • Para que Notepad ++ use finales de línea Unix como valor predeterminado, vaya a la configuración del menú -> Preferencias. En el cuadro de diálogo, seleccione la pestaña Nuevo documento/Directorio predeterminado. En la sección Formato que forma parte de la sección Nuevo documento, seleccione el final de línea que desee. ADVERTENCIA: No seleccione Mac como opción. Eso ni siquiera funciona en Mac. Si tiene una Mac, seleccione Unix.
+0

Gracias, lo intentaré. Por cierto, yo estaba usando Wordpad, y eso probablemente causa el problema ... – Frencoo

1

Ejecución material de Windows en cygwin tiene un desagradable efecto secundario como lo encontró a cabo - la captura de la salida de los programas de Windows en una variable de bash Cygwin también capturará la salida de CR por el programa.

uso juicioso de d2u evita el tema - por ejemplo,

runtime="`mediainfo --Inform='Video;%Duration%' ${movie} | d2u`" 

(Sin la d2u, $ {tiempo de ejecución} tendría un CR clavado en el extremo, lo que provoca el problema que viste cuando le da de comer a 'bc', por ejemplo.)

Cuestiones relacionadas