J'ai écrit un script shell pour tester une API qui copie des fichiers et fait écho à sa progression après chacun.
Il y a un sommeil de deux secondes entre chaque copie, donc je voudrais ajouter la possibilité d'appuyer sur n'importe quelle touche pour suspendre le script pour permettre des tests plus approfondis. Appuyez ensuite sur n'importe quelle touche pour reprendre.
Comment puis-je ajouter cela en aussi peu de lignes que possible?
shell-script
blarg
la source
la source
sleep 10; notify-send hello
et appuie sur CTRL + Z pour arrêter, exécutez -notify-send hello
vous. si la deuxième commande est exécutée, comment se fait-il que le premier processus soit arrêté? après cela, si le type quefg
je ne vois rien se passe, ce qui est évident, car la deuxième commande est déjà exécutéecmd; cmd; cmd;
c'est comme écrirecmd <newline> cmd <newline> ...
. Alternativement à un script que vous pouvez écrire( cmd; cmd; cmd; )
, il se comporterait comme le script, bacuse du sous-shell généré par(
sleep 10
. lorsque j'appuie sur CTRL + Z après 3 secondes et que je reprends après quelques secondes et que j'ai remarqué que la commande de sommeil est morte en moins de 7 secondes. ce qui est contraire à ce que vous avez dit, puisque la commande ne s'arrête jamais, elle s'exécute en arrière-plan.strace
lasleep
commande et j'ai découvert que l'appel système utilisé étaitnanosleep()
. Cela semble être un comportement défini de l'nanosleep
appel système.restart_syscall()
redémarre l'appel système interrompu avec un argument de temps qui est convenablement ajusté pour tenir compte du temps qui s'est déjà écoulé (y compris le temps où le processus a été arrêté par un signal). Lisez cette page de manuelfg %1
ou à l'arrière-plan (ex:)bg %1
. (si les travaux ne donnent qu'un seul numéro, c'est-à-dire un seul processus suspendu, comme dans l'exemple chaos l'a montré: seulement[1]+ stopped sleep 10
, vous pouvez omettre la%n
partie. s'il y a plusieurs processus d'arrière-plan (en cours ou arrêtés), vous devez désigner celui que vous voulez avec:%n
(ex:fg %2
pour faire reprendre% 2 au premier plan))Si vous voulez simplement suspendre le script tout en restant à l'intérieur du script, vous pouvez utiliser la lecture au lieu de la veille.
Vous pouvez utiliser
read -t
pour définir un délai d'attente pour la lectureread -n
pour lire un caractère (appuyez simplement sur n'importe quelle touche) pour continuer le scriptComme vous n'avez fourni aucun code, voici un exemple de la façon dont il pourrait être utilisé.
Si vous appuyez sur q, cela
read -n1
empêche le script de continuer jusqu'à ce qu'une touche soit enfoncée.Lorsqu'une touche est enfoncée, la vérification est réinitialisée et le script continue normalement dans la boucle.
Vous pouvez également ajouter
stty -echo
au début de la section etstty echo
à la fin pour empêcher la saisie de gâcher la sortie d'écranla source
Avec,
dd
vous pouvez lire de manière fiable un seul octet à partir d'un fichier. Avec,stty
vous pouvez définir unmin
certain nombre d'octets pour qualifier une lecture de terminal et unetime
sortie en dixièmes de seconde. Combinez ces deux et vous pouvez vous en passersleep
entièrement, je pense, et laissez simplement le délai de lecture du terminal faire le travail pour vous:C'est une petite
while
boucle d' exemple que j'ai simulée pour que vous l'essayiez. Toutes les deux secondesdd
, sa tentative de lecturestdin
- redirigé depuis/dev/tty
- et lawhile
boucle bouclent. Cela oudd
n'expire pas car vous appuyez sur une touche - auquel cas un shell interactif est appelé.Voici un test - les nombres imprimés en tête de chaque ligne sont la valeur de la variable shell
$SECONDS
:la source
stty sane
après avoir modifié le paramètre stty, je me trompe peut-être, mais il ne semble pas que vous les ayez réinitialisés quelque part?s=$(stty -g </dev/tty)
. Immédiatement après avoir appelé,dd
je le restaure avecstty "$s"
. L'état du terminal ne se soucie pas des sous-boîtiers et ces paramètres restent donc indépendants du shell parent.stty sane
n'est pas nécessairement ce que vous voulez faire - il vaut mieux restaurer l'état tel que vous l'avez trouvé que de supposer que l'état étaitsane
à ce moment-là. Si je ne le restaurais pas, cesecho
s seraient partout. Comprendre cela est en partie pourquoi je suis arrivé si tard - votre réponse n'était pas là quand j'ai commencé les tests.