1

I'm working on a SunOS 5.11/Solaris 11.3 machine. I have a bash script that calculates and exports CPU frequency because I use it frequently in some test scripts.

Here are the two lines of interest:

solaris:~$ CPU_FREQ=$(psrinfo -v 2>/dev/null | grep 'MHz' | head -1 | awk '{print $6}')
solaris:~$ echo $CPU_FREQ
3000
solaris:~$ CPU_FREQ=$(awk "BEGIN {print $CPU_FREQ/1024/1024}")
^C

Why does the awk command hang under Solaris? And what should I be doing different?


Here's the larger view of the script. It works well under Linux, OS X and the BSDs.

IS_LINUX=$(uname -s | grep -i -c linux)
IS_DARWIN=$(uname -s | grep -i -c darwin)
IS_SOLARIS=$(uname -s | grep -i -c sunos)

# 2.0 GHz or 2.0/1024/1024/1024
CPU_FREQ=1.8189894
if [ "$IS_LINUX" -ne "0" ] && [ -e "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ]; then
    CPU_FREQ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
    CPU_FREQ=$(awk "BEGIN {print $CPU_FREQ/1024/1024}")
elif [ "$IS_DARWIN" -ne "0" ]; then
    CPU_FREQ=$(sysctl -a 2>/dev/null | grep 'hw.cpufrequency' | head -1 | awk '{print $3}')
    CPU_FREQ=$(awk "BEGIN {print $CPU_FREQ/1024/1024/1024}")
elif [ "$IS_SOLARIS" -ne "0" ]; then
    CPU_FREQ=$(psrinfo -v 2>/dev/null | grep 'MHz' | head -1 | awk '{print $6}')
    CPU_FREQ=$(awk "BEGIN {print $CPU_FREQ/1024}")
fi

# Used by Crypto++ benchmarks
export CPU_SPEED=$CPU_FREQ

Here's the output of psrinfo:

$ psrinfo -v
Status of virtual processor 0 as of: 06/07/2016 18:23:29
  on-line since 06/07/2016 14:28:28.
  The i386 processor operates at 3000 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 1 as of: 06/07/2016 18:23:29
  on-line since 06/07/2016 14:28:34.
  The i386 processor operates at 3000 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 2 as of: 06/07/2016 18:23:29
  on-line since 06/07/2016 14:28:34.
  The i386 processor operates at 3000 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 3 as of: 06/07/2016 18:23:29
  on-line since 06/07/2016 14:28:34.
  The i386 processor operates at 3000 MHz,
        and has an i387 compatible floating point processor.
3

Use nawk under Solaris.

/usr/bin/awk is the legacy, non POSIX awk with which a script only containing a BEGIN action isn't skipping its stdin.

The following statement is appearing in the nawk and /usr/xpg4/bin/awk manual but not in the old awk one:

If an nawk program consists of only actions with the pattern BEGIN, and
the BEGIN action contains no getline function, nawk exits without read-
ing  its input when the last statement in the last BEGIN action is exe-
cuted.

By the way, there is no need to run head, grep, andtwo awk scripts. One awk script can do all of this alone:

 CPU_FREQ=$(psrinfo -v 2>/dev/null | nawk '/MHz/ {print $6/1024;exit}')
  • Perfect, thank you very much. I'm not sure about the statement in the man pages, but nawk calculates the expected CPU speed. I'm guessing the part about exiting does not apply. – user56041 Jun 7 '16 at 23:12
  • 2
    awk calculates the expected CPU speed too but it waits for an input that never shows up. The part about exiting definitely applies. – jlliagre Jun 7 '16 at 23:28
  • Oh, I see. Thanks. I am definitely behind the curve with respect to Solaris... Its frustrating because I'm somewhat proficient in Linux, OS X and Windows. Its like learning to crawl again. – user56041 Jun 8 '16 at 1:25
  • 2
    An alternative would be to set your PATH this way PATH=/usr/gnu/bin:$PATH; in that case the GNU utilities would be picked by your scripts, for example awk would be GNU awk and would have worked as you expect. – jlliagre Jun 8 '16 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy