Search code examples
bashsorting

Improving sleep sort in bash


I came across this nifty bash script, that is a little borked.

#!/bin/bash
function f() {
    sleep "$1"
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait

It sleeps for the seconds given by the number, then outputs that number. The lowest numbers wake up first.

I was thinking it could be improved by first dividing the numbers by the maximum number in the list, then running it through, and multiplying by the max as it exits.

Here's my first attempt:

#!/bin/bash

declare -a to_sort

function f() {
    sleep "$1"
    final_var=$(echo "$1*$2"|bc)
    echo "$1"
}
function max(){
for var in "$@"
do
    if [ "$var" -gt "$max" ] # Using the test condition
    then
        max="$var"
    fi
done
}

echo "$1"| read -a to_sort

let max_var = max to_sort

for i in "${to_sort[@]}"
do
    parsed_var=$(echo "$i/$max_var"|bc)
    f parsed_var max_var &
    shift
done
wait

Where am I going wrong?


Solution

  • There were 7 issues in syntax and logic that prevented this from working, as commented below.

    #!/bin/bash
    
    declare -a to_sort
    
    function f() {
        sleep "$1"
        final_var=$(echo "$1*$2"|bc)
        #Output result after multiplication
        #and skip decimals
        echo "${final_var%.*}"
    }
    function max(){
    # Initialize max so we have something to compare against
    max=$1
    for var in "$@"
    do
        if [ "$var" -gt "$max" ]
        then
            max="$var"
        fi
    done
    # output the max we found
    echo $max
    }
    
    # Avoid assigning in subshells
    read -a to_sort <<< "$1"
    #This is how you assign the output of a command
    max_var=$(max "${to_sort[@]}")
    
    for i in "${to_sort[@]}"
    do
        # Add scale to avoid truncating all to 0
        parsed_var=$(echo "scale=6; $i/$max_var"|bc)
    
        # expand variables
        f $parsed_var $max_var &
        shift
    done
    wait                            
    

    Also note that GNU sleep handles fractions but many other OS don't.