Redireccionar la salida del comando al archivo

1

Esto parece tan simple cuando lo hago desde la línea de comandos, pero no puedo lograrlo dentro de un script. Estoy tratando de poner la salida del siguiente comando en un archivo de texto:

CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'
FIL=~/replication-`date +%F`.txt
MAILTEXT=~/mailtext.txt

touch $FIL
$CMD > $FIL

Donde FILes una variable que contiene la ruta del archivo al que se envía el comando. Estoy ejecutando este comando en un script de shell desde donde quiero enviar contenido por correo electrónico $FILcomo adjunto usando mutt. Pero siempre obtengo un archivo de 0 bytes. Además, si examino en el directorio, el archivo tiene una longitud de 0 bytes.

TheIdiot de la aldea
fuente
¿Qué pasa si lo hace? (mysql -uroot -psecret -e 'SHOW SLAVE STATUS \ G;')> $ FILE
barlop
@barlop He actualizado la pregunta con script real.
TheVillageIdiot
Su primera asignación a CMDno funcionará, deshacerse del espacio después =y rodear los valores con comillas dobles: shes extremadamente extraño en su tratamiento del espacio en blanco.
reinierpost

Respuestas:

3

El problema no está en la redirección, sino en cómo está almacenando el comando en una variable. Primero, no puedes poner un espacio después =de la asignación; con el espacio allí, establece CMD en blanco y ejecuta el comando mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'. Si solo elimina el espacio, configurará CMD en "mysql" e intentará ejecutar el comando -uroot -psecret -e 'SHOW SLAVE STATUS \G;'. Entonces, como sugirió @ Michał Šrajer, podría envolverlo entre comillas dobles para que todo se asigne a CMD. Pero todavía no funciona, porque cuando $CMDse expande, no presta atención a las citas dentro de él. Cuando bash analiza una línea de comando, analiza las comillas antes de expandir las variables, por lo que poner comillas dentro de una variable no hace nada útil.

Almacenar un comando en una variable es complicado. BashFAQ # 50 tiene algunas buenas discusiones y opciones. En este caso, las opciones que me parecen relevantes son:

  1. No pongas el comando en una variable en primer lugar. Si no hay una buena razón para ello, no lo hagas:

    FIL=~/replication-`date +%F`.txt
    MAILTEXT=~/mailtext.txt
    
    touch $FIL
    mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;' > $FIL
  2. Si debe poner el comando en una variable, use una matriz en lugar de una variable de texto simple. En este caso, las comillas se analizarán cuando se cree la variable y, si la usa, se conservarán "${varname[@]}"los saltos entre "palabras":

    CMD=(mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;')
    FIL=~/replication-`date +%F`.txt
    MAILTEXT=~/mailtext.txt
    
    touch $FIL
    "${CMD[@]}" > $FIL
Gordon Davisson
fuente
gracias, el primero funcionó pero el segundo dio este error: `Error de sintaxis:" ("inesperado"
TheVillageIdiot
¿Este script lo ejecuta bash o algún otro shell? Las matrices son una extensión, por lo que más shells básicos no las admitirán. Asegúrese de que el shebang (primera línea del guión) es #!/bin/bash.
Gordon Davisson
0

cambio:

CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'

a:

CMD="mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'"
Michał Šrajer
fuente
0

He creado un script similar que funciona:

FIL=~/test.txt
CMD="hostname"
touch $FIL
$CMD > $FIL

¿Intentó sin la redirección primero, para ver si las salidas se generan en absoluto?

BennyInc
fuente