Pregunta

Me encontré con el siguiente problema: Estoy escribiendo un script bash de Linux, que hace lo siguiente:

  • Leer la línea del archivo
  • Pelar el carácter \n desde el final de la línea acaba de leer
  • Ejecutar el comando que hay ahí

Ejemplo: commands.txt

ls
ls -l
ls -ltra
ps as

La ejecución del archivo fiesta debe recibir la primera línea, y ejecutarlo, pero mientras que el \n presente, el shell solo salidas "comando no encontrado: ls" Esa parte de la secuencia de comandos se parece a esto

 read line

        if [ -n "$line" ]; then #if not empty line

                #myline=`echo -n $line | tr -d '\n'`
                #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`

                myline=`echo -n $line | tr -d "\n"`
                $myline  #execute it

                cat $fname | tail -n+2 > $fname.txt
                mv $fname.txt $fname
        fi

Comentadas usted tiene las cosas que intenté antes de pedir SO. ¿Soluciones? Estoy rompiendo mi cerebro durante el último par de horas sobre esto ...

¿Fue útil?

Solución

Siempre me gusta perl -ne 'chomp and print', para recortar los saltos de línea. Agradable y fácil de recordar.

por ejemplo. ls -l | perl -ne 'chomp and print'

Sin embargo

No creo que ese es su problema aquí, sin embargo. Aunque no estoy seguro de entender cómo se está pasando los comandos en el archivo a través de la 'leer' en su secuencia de comandos shell.

Con un guión de prueba de mi propia como esto (test.sh)

read line
if [ -n "$line" ]; then
  $line
fi

y un archivo de entrada de ejemplo como esto (test.cmds)

ls 
ls -l
ls -ltra

Si lo ejecuto como esto ./test.sh < test.cmds, veo el resultado esperado, que se va a ejecutar el primer comando 'ls' en el directorio de trabajo actual.

Tal vez el archivo de entrada tiene caracteres no imprimibles adicionales en ella?

mío se parece a esto

od -c test.cmds 
0000000    l   s      \n   l   s       -   l  \n   l   s       -   l   t
0000020    r   a  \n                                                    
0000023

A partir de los comentarios de abajo, que sospecha que puede tener retornos de carro ( "\ r") en el archivo de entrada, que no es lo mismo que una nueva línea. Es el archivo de entrada originalmente en formato DOS? Si es así, entonces usted necesita para convertir la línea DOS 2 bytes terminación "\ r \ n" al único byte UNIX uno, "\ n" para lograr los resultados esperados.

Usted debe ser capaz de hacer esto mediante el canje de la "\ n" para "\ r" en cualquiera de sus líneas comentadas.

Otros consejos

Alguien ya escribió un programa que ejecuta los comandos shell: sh archivo

Si realmente sólo desea ejecutar la primera línea de un archivo: head -n 1 file |sh

Si su problema es retornos de carro: tr -d '\r' <file |sh

He intentado esto:

read line
echo -n $line | od -x

Para la entrada 'xxxx', me sale:

0000000 7878 7878

Como se puede ver, no hay \n al final del contenido de la variable. Sugiero para ejecutar el script con la opción -x (bash -x script). Esto imprimirá todos los comandos que se ejecutan.

[EDIT] Su problema es que ha editado commands.txt en Windows. Ahora, el archivo contiene CRLF (0d0a) como delimitadores de línea que confunde read (y ls\r no es un comando conocido). Utilice dos2unix o similar a convertirlo en un archivo de Unix.

También puede tratar de sustituir los retornos de carro con saltos de línea única utilizando órdenes internas del golpe:

line=$'a line\r' 
line="${line//$'\r'/$'\n'}" 
#line="${line/%$'\r'/$'\n'}"       # replace only at line end
printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 

necesita comando eval


#!/bin/bash -x

while read  cmd
do
 if [ "$cmd" ]
 then
  eval "$cmd"
 fi
done

Me encontré como
./script.sh

Y archivo.txt fue:

ls
ls -l
ls -ltra
ps as

a pesar de que no trabaja para ls, recomiendo echar un vistazo a find 's opción -print0

funciona de la siguiente secuencia de comandos (al menos para mí):

#!/bin/bash

while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top