Arman
Arman

Reputation: 4626

How to extend bash shell?

would like to add new functionality to the bash shell. I need to have a queue for executions.

What is the easy way to add new functionality to the bash shell keeping all native functions? I would like to process the command line, then let the bash to execute them. For users it should be transparent.

Thanks Arman

EDIT

I just discovered prll.sourceforge.net it does exactly what I need.

Upvotes: 3

Views: 3024

Answers (1)

technosaurus
technosaurus

Reputation: 7802

Its easier than it seems:

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

while read COMMANDS; do
  eval "$COMMANDS"
done

you can use read -p if you need a prompt or -t if you want it to timeout ... or if you wanted you could even use your favorite dialog program in place of read and pipe the output to a 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 &

To execute commands in threads you can use the following in place of 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

Then there is the case where you fill up all threads. You can either put the whole thing in a while loop and add continues and breaks, or you can pick a core to wait for (probably the last) and wait for it

to wait for a single thread to complete use:

wait $threadarray[$i]

to wait for all threads to complete use:

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

another note: you may find that some commands don't like to be threaded, if so you can put the whole thing in a case statement

I'll try to do some cleanup on this soon to put all of the little blocks together (sorry, I'm cobbling this together from random notes that I used to implement this exact thing, but can't seem to find)

Upvotes: 2

Related Questions