GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es posible hacer que un script bash shell interactúe con otro programa de línea de comandos?

Si a su comando no le importa qué tan rápido lo ingresa, y realmente no necesita interactuar con él, entonces puedes usar un heredoc.

Ejemplo:

#!/bin/bash
prog <<EOD
cmdx
save filex
cmdy
save filey
q
EOD

Si necesita una bifurcación basada en la salida del programa, o si su programa es sensible al tiempo de sus comandos, entonces Expect es lo que desea.


Te recomiendo que uses Expect. Esta herramienta está diseñada para automatizar aplicaciones de shell interactivas.


¡Donde hay una necesidad, hay un camino! Creo que es una buena lección de bash para ver cómo funciona la gestión de procesos y el ipc. La mejor solución es, por supuesto, Expect. Pero la verdadera razón es que las tuberías pueden ser complicadas y muchos comandos están diseñados para esperar datos, lo que significa que el proceso se convertirá en un zombi por razones que son difíciles de predecir. Pero aprender cómo y por qué nos recuerda lo que sucede debajo del capó.

Cuando dos procesos entablan una conversación, el peligro es que uno o ambos intenten leer datos que nunca llegarán. Las reglas de enfrentamiento tienen que ser muy claras. Cosas como CRLF y la codificación de caracteres pueden matar a la fiesta. Afortunadamente, dos socios cercanos como un script bash y su proceso secundario son relativamente fáciles de mantener en línea. Lo más fácil de pasar por alto es que bash está lanzando un proceso secundario para casi todo lo que hace. Si puede hacer que funcione con bash, sabe perfectamente lo que está haciendo.

El punto es que queremos hablar con otro proceso. Aquí hay un servidor:

# a really bad SMTP server

# a hint at courtesy to the client
shopt -s nocasematch

echo "220 $HOSTNAME SMTP [$$]"

while true
do
    read
    [[ "$REPLY" =~ ^helo\ [^\ ] ]] && break
    [[ "$REPLY" =~ ^quit ]] && echo "Later" && exit
    echo 503 5.5.1 Nice guys say hello.
done

NAME=`echo "$REPLY" | sed -r -e 's/^helo //i'`
echo 250 Hello there, $NAME 

while read
do
    [[ "$REPLY" =~ ^mail\ from: ]] && { echo 250 2.1.0 Good guess...; continue; }
    [[ "$REPLY" =~ ^rcpt\ to: ]] && { echo 250 2.1.0 Keep trying...; continue; }
    [[ "$REPLY" =~ ^quit ]] && { echo Later, $NAME; exit; }
    echo 502 5.5.2 Please just QUIT
done

echo Pipe closed, exiting

Ahora, el guión que con suerte hace la magia.

# Talk to a subprocess using named pipes

rm -fr A B      # don't use old pipes
mkfifo A B

# server will listen to A and send to B
./smtp.sh < A > B &

# If we write to A, the pipe will be closed.
# That doesn't happen when writing to a file handle.
exec 3>A

read < B
echo "$REPLY"

# send an email, so long as response codes look good
while read L
do
    echo "> $L"
    echo $L > A
    read < B
    echo $REPLY
    [[ "$REPLY" =~ ^2 ]] || break

done <<EOF
HELO me
MAIL FROM: me
RCPT TO: you
DATA
Subject: Nothing

Message
.
EOF

# This is tricky, and the reason sane people use Expect.  If we
# send QUIT and then wait on B (ie. cat B) we may have trouble.
# If the server exits, the "Later" response in the pipe might
# disappear, leaving the cat command (and us) waiting for data.
# So, let cat have our STDOUT and move on.
cat B &

# Now, we should wait for the cat process to get going before we
# send the QUIT command. If we don't, the server will exit, the
# pipe will empty and cat will miss its chance to show the
# server's final words.
echo -n > B     # also, 'sleep 1' will probably work.

echo "> quit"
echo "quit" > A

# close the file handle
exec 3>&-

rm A B

Tenga en cuenta que no estamos simplemente volcando los comandos SMTP en el servidor. Verificamos cada código de respuesta para asegurarnos de que todo esté bien. En este caso, las cosas no saldrán bien y el guión se irá.


Linux
  1. ¿Qué intérprete de Shell ejecuta un script sin Shebang?

  2. ¿Cómo pasar un argumento de línea de comando a un script de Shell?

  3. ¿La secuencia de comandos Bash con `set -e` no se detiene en el comando `… &&…`?

  4. Bash Echo ¿La línea de comando se ejecutó en la propia línea de comando (no en un script)?

  5. Shell Script Wrapper para evitar la ejecución de comandos sin argumentos?

Cómo programar con Bash:Sintaxis y herramientas

Shell Scripting Parte I:Primeros pasos con bash scripting

Comando Bash Echo explicado con ejemplos en Linux

Cómo hacer eco de una nueva línea en Bash Shell Scripts

Automatice mysql_secure_installation con el comando echo a través de un script de shell

texto de eco con nueva línea en bash