Necesito hacer muchas copias de varios archivos en varias carpetas. Puedo agregar todos mis comandos de copia a un script bash y luego ejecutar eso, pero luego debo esperar hasta que termine si quiero agregar más comandos a esa "cola" de copia.
¿Hay alguna forma de ejecutar comandos como una cola y agregar más comandos a esa cola mientras las cosas se están ejecutando?
Explicado de una manera diferente, quiero comenzar una tarea de larga duración. Mientras se está ejecutando, quiero iniciar otro que no se inicie hasta que se complete el primero. Y luego agregue otro después del último y así sucesivamente. ¿Es esto posible de alguna manera?
Respuestas:
La
at
utilidad, mejor conocida por ejecutar comandos en un momento específico, también tiene una función de cola y se le puede pedir que comience a ejecutar comandos ahora. Lee el comando para ejecutar desde la entrada estándar.El
batch
comando es equivalente aat -q b -m now
(lo que-m
significa que la salida del comando, si la hay, se le enviará por correo, como lo hace cron). No todas las variantes de Unix admiten nombres de cola (-q myqueue
); puede estar limitado a una sola cola llamadab
. Linuxat
está limitado a nombres de cola de una letra.fuente
now
, no-t now
, lo siento. No me había dado cuenta de que estaba equivocado en el código de muestra.Agregue
&
al final de su comando para enviarlo al fondo, y luegowait
en él antes de ejecutar el siguiente. Por ejemplo:fuente
wait
? Parece impermeable a todos mis asesinatos.wait
simplemente se detiene el trabajo hasta que terminen las anteriores.nohup
?Las soluciones de Brad y Mankoff son buenas sugerencias. Otro que es similar a una combinación de ambos les sería utilizar GNU Screen para implementar su cola. Esto tiene la ventaja de poder ejecutarse en segundo plano, puede verificarlo cuando lo desee y poner en cola nuevos comandos simplemente los pega en el búfer para que se ejecuten después de que salgan los comandos anteriores.
Primer intento:
(por cierto, ahora es un buen momento para jugar con algunos archivos impresionantes. screenrc )
Eso generará una sesión de pantalla de fondo para usted llamada cola.
Ahora, ponga en cola tantos comandos como desee:
Estoy haciendo múltiples comandos en lo anterior solo para probar. Su caso de uso probablemente se parecería más a:
Tenga en cuenta que la "^ M" en mi línea anterior es una forma de obtener una nueva línea incrustada que se interpretará más tarde después de que la pantalla la inserte en su shell de bash existente. Use "CTL-V" para obtener esa secuencia.
Sería bastante fácil crear algunos scripts de shell simples para automatizar eso y poner en cola los comandos. Luego, cada vez que desee verificar el estado de su cola en segundo plano, se vuelve a adjuntar a través de:
Técnicamente, ni siquiera necesita nombrar su sesión de pantalla y funcionará bien, pero una vez que se enganche, querrá dejar una en ejecución todo el tiempo de todos modos. ;-)
Por supuesto, si haces eso, otra buena manera de hacerlo sería nombrar una de las ventanas actuales "cola" y usar:
fuente
Hay una utilidad que he utilizado con gran éxito exactamente para el caso de uso que está describiendo. Recientemente trasladé mi computadora portátil principal a un nuevo hardware, lo que implicó mover algunos archivos a un NAS y el resto a la nueva máquina.
Así es como lo hice.
Configure todas las máquinas involucradas con una conexión de red para que puedan comunicarse entre sí.
En la máquina desde la que está moviendo los archivos (en adelante, la máquina fuente), instale rsync con
apt-get install rsync
y la Tarea Spooler de secret-sauce (sitio web http://vicerveza.homeunix.net/~viric/soft/ts/ ). Si está en Debian, el nombre del paquetets
es istask-spooler
y se cambia eltsp
nombre delts
ejecutable para evitar el choque de nombres con el ejecutable delmoreutils
paquete. El paquete Debian vinculado desde el sitio web es perfectamente instalable en Ubuntu condpkg -i task-spooler_0.7.3-1_amd64.deb
o similar.También asegúrese de que todas las máquinas tengan SSH instalado
apt-get install openssh-server
. En la máquina de origen, debe configurar SSH para permitir el inicio de sesión sin contraseña en las máquinas de destino. El método que la mayoría usará es la autenticación de clave pública conssh-agent
(consulte https://www.google.se/search?q=ssh+public+key+authentication para ver ejemplos de eso), pero a veces uso un método más fácil que funciona solo también con autenticación de contraseña. Agregue lo siguiente a la configuración de su cliente SSH (ya sea~/.ssh/config
o/etc/ssh/ssh_config
):Luego abra una terminal en la máquina fuente, inicie sesión
ssh target1
, autentíquese como de costumbre y luego deje esta terminal abierta. Observe que hay un archivo de socket llamado~/.ssh/master-user@target1:22
, este es el archivo que mantendrá abierta una sesión maestra autenticada y permitirá conexiones sin contraseña posterioresuser
(siempre que la conexión use el mismo nombre de host y puerto de destino).En este punto, debe verificar que puede iniciar sesión sin que se le solicite la autenticación en las máquinas de destino.
Ahora ejecute
ts rsync -ave ssh bigfile user@target1:
para un solo archivo ots rsync -ave ssh bigdir user@target1:
para un directorio. Con rsync es importante no incluir una barra inclinada final en el directorio (enbigdir
comparación conbigdir/
) o rsync supondrá que se refería al equivalente de labigdir/*
mayoría de las otras herramientas.Task Spooler devolverá el mensaje y le permitirá poner en cola muchos de estos comandos en sucesión. Inspeccione la cola de ejecución
ts
sin argumentos.Task Spooler tiene muchas características, como reorganizar la cola de ejecución, ejecutar un trabajo específico solo si otro trabajo se ejecutó correctamente, etc. Consulte la ayuda con
ts -h
. A veces inspecciono la salida del comando mientras se ejecuta conts -c
.Existen otros métodos para hacer esto, pero para su caso de uso, todos incluyen Task Spooler. Elijo usar rsync a través de SSH para preservar las marcas de tiempo del archivo, que la copia a través de SMB no tendría.
fuente
ts
, parece muy potente y fácil de usar, solo bifurcado en github autotoolizado y debianizado.task-spooler
:-) ... de todos modos, eso es en tu comentario es una muy buena sugerencia, lo haré muy pronto.Necesito cosas como esta con bastante frecuencia también. Escribí una pequeña utilidad llamada
after
que ejecuta un comando cada vez que algún otro proceso ha finalizado. Se parece a esto:Luego lo ejecutas así:
La gran ventaja de esto sobre algunos otros enfoques es que el primer trabajo no necesita ejecutarse de ninguna manera especial, puede seguir cualquier proceso con su nuevo trabajo.
fuente
Command1 && Command2
fuente
Simplemente puede agregar comandos a la línea de comandos del shell que ya está ejecutando un comando.
Escriba con cuidado o escríbalo en otro lugar, verifique y corte y pegue. Incluso si el comando actual arroja líneas de salida, puede escribir algo nuevo, presionar enter y se ejecutará cuando todos los comandos se ejecuten o ingresen antes de que se complete.
El siguiente ejemplo. Puede cortar y pegar todo, o ingresar los comandos posteriores mientras se ejecuta el primero (si escribe realmente muy rápido), o más probablemente mientras el segundo está en ejecución .:
fuente
La forma más complicada que se me ocurre es mantener el "estado" de la cola con simples archivos de bloqueo en / tmp. cuando file1.sh está haciendo sus comandos cp, mantendrá un archivo de bloqueo (o enlace duro) en / tmp. cuando termine, borre el archivo. cualquier otro script tendrá que buscar en / tmp los archivos de bloqueo con el esquema de nombres que elija. naturalmente, esto está sujeto a todo tipo de fallas, pero es trivial de configurar y se puede hacer completamente dentro de bash.
fuente