2010-10-02 5 views
3

souhaite ajouter de nouvelles fonctionnalités à l'interpréteur de commandes bash. J'ai besoin d'une file d'attente pour les exécutions.Comment faire pour étendre shell bash?

Quel est le moyen facile d'ajouter de nouvelles fonctionnalités au shell bash en gardant toutes les fonctions natives? Je voudrais traiter la ligne de commande, puis laisser le bash pour les exécuter. Pour les utilisateurs, cela devrait être transparent.

Merci Arman

EDIT

Je viens de découvrir prll.sourceforge.net il fait exactement ce que je dois.

+1

que voulez-vous dire "file d'attente pour les exécutions"? Parlez-vous de l'exécution de plusieurs commandes en même temps? Si oui, bash fait cela, il suffit de séparer les commandes avec un point-virgule. – ubiquibacon

+0

Oui, mais je veux dire: asumming a & b & c & d, et vous avez seulement 2 processeurs, je voudrais exécuter seulement 2 processus en même temps. – Arman

+4

Bien que ce ne soit pas une solution générale, si vous voulez exécuter la même commande en parallèle sur une liste d'arguments, alors les balises 'xargs' et' -P' peuvent le faire, tout comme ['parallel'] (http: // en.wikipedia.org/wiki/Parallel_ (software \)), qui prend également en charge le commutateur '-j + 0', détectant automatiquement le nombre de CPU. – Nick

Répondre

2

Il est plus facile qu'il n'y paraît:

#!/bin/sh 
yourfunctiona(){ ...; } 
... 
yourfunctionz(){ ...; } 
. /path/to/file/with/more/functions 

while read COMMANDS; do 
    eval "$COMMANDS" 
done 

vous pouvez utiliser -p lire si vous avez besoin d'une invite ou -T si vous le souhaitez ... délai d'attente ou si vous voulez vous pouvez même utiliser votre favori programme de dialogue en place de lecture et redirigez la sortie à un tailbox

touch /tmp/mycmdline 
Xdialog --tailbox /tmp/mycmdline 0 0 & 
COMMANDS="echo " 
while ([ "$COMMANDS" != "" ]); do 
    COMMANDS=`Xdialog --stdout --inputbox "Text here" 0 0` 
    eval "$COMMANDS" 
done >>/tmp/mycmdline & 

pour exécuter des commandes dans des threads, vous pouvez utiliser les éléments suivants à la place de eval $ COMMANDS

#this will need to be before the loope 
NUMCORES=$(awk '/cpu cores/{sum += $4}END{print sum}' /proc/cpuinfo) 

for i in {1..$NUMCORES};do 
    if [ $i -eq $NUMCORES ] && #see comments below 
    if [ -d /proc/$threadarray[$i] ]; then #this core already has a thread 
#note: each process gets a directory named /proc/<its_pid> - hacky, but works 
    continue 
    else #this core is free 
    $COMMAND & 
    threadarray[$i]=$! 
    break 
fi 
done 

Ensuite, il y a le cas où vous remplissez tous les threads. Vous pouvez mettre le tout dans une boucle while et ajouter continue et les pauses, ou vous pouvez choisir un noyau d'attendre (probablement la dernière) et attendez qu'il

d'attendre un seul thread pour compléter l'utilisation :

wait $threadarray[$i] 

à attendre que toutes les discussions pour compléter l'utilisation:

wait 
#I ended up using this to keep my load from getting to high for too long 

une autre note: vous pouvez constater que certaines commandes n'aiment pas être enfilée, le cas échéant, vous pouvez mettre la chose en une déclaration de cas

Je vais essayer de faire un peu de nettoyage sur ce point bientôt pour mettre tous les petits blocs ensemble (désolé, je suis en train de concocter cela ensemble à partir de notes aléatoires que j'ai utilisées pour mettre en œuvre exactement, mais ne peut pas trouver)

+0

intéressant, mais où avez-vous organisé le pool de threads? – Arman

+0

désolé, ce serait quelques lignes supplémentaires en fonction du nombre de threads que vous voulez soutenir (Il semblait que vous aviez déjà une fonction pour cela) ... préférez-vous un code plus simple avec des bashismes ou plus long mais plus portable shell qui fonctionnera avec busybox ash/chut? – technosaurus

+0

par exemple je peux paralléliser les appels avec make -j ntreads, si j'écris Makefile correct, mais avec bash son petit peu non trivial pour moi. – Arman

Questions connexes