Beta testers needed
Forum: Programming and Scripting
Topic: Beta testers needed
started by: Zucca
Posted by Zucca on Jan. 24 2008,16:16
Here it is. A system statistics script. Highly customizable.
Copy and paste this and run it with bash. Then post results and comments. Anything is welcome. ;)
Code Sample | #!/bin/bash # sysinfo.sh
# This script uses /proc filesystem and at least following utilities: # sed, perl/bc and grep # # Run from command line with --help switch to get more help.
# Feel free to change this if you are too lazy to set an alias.;) # Note: You can have custom ouput from command line too. Just see --help. DEFAULT_FORMAT="Uptime: -UPTIME- | % idle since boot: -IDLEPERCENT- | \ -CPUMODEL- @ -CPUSPEED- | \ Bogomips: -BOGOMIPS- | \ Mem total/used/free: -MEMTOTAL-/-MEMUSAGE-/-MEMFREE-"
# No need to edit more. =) ############################################################################
BASENAME=`basename $0` VERSION="1.10.1b"
case $@ in
*--licence*) # We saw user requesting lience... echo "$BASENAME version $VERSION
############################################################################ ### LICENCE -start- ######################################################## ############################################################################ # #Copyright (c) 2008, Zucca # # All rights reserved. #Redistribution and use in source and binary forms, with or without #modification, are permitted provided that the following conditions are met: # - Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # - Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # - Neither the name of the Zucca's company nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ############################################################################ ### LICENCE -end- ########################################################## ############################################################################ ";;
*--help*) # User wants some help... echo "${BASENAME} version $VERSION
USAGE: ${BASENAME} [--uptimeweeks] [--mmega] [OUTPUT FORMAT] USAGE: ${BASENAME} [--help] USAGE: ${BASENAME} [--licence]
OUTPUT FORMAT can have any text you like (${BASENAME} will use echo with \ no argument to print information, so use your head.), but ${BASENAME} will \ replace following:\n\ -UPTIME- will show system uptime. --uptimeweeks will tell uptime in weeks \ if uptime is seven days or more. -IDLEPERCENT- displays percentage of idle time from uptime. -CPUMODEL- diplays your CPU model. -CPUSPEED- displays the clockspeed of your processor. -CPUCACHE- shows size of your CPU cache. -BOGOMIPS- see http://en.wikipedia.org/wiki/Bogomips -MEMTOTAL- will display amout of total physical (RAM) memory in your system. -MEMUSAGE- same as above but displays used memory -MEMFREE- same as above but displays free memory
Note: switches can be in any order as long as they are before OUTPUT FORMAT
Example: ${BASENAME} -UPTIME- will show you uptime in days, hours, minutes and seconds.
If OUTPUT FORMAT does not contain any text it defaults to: ${DEFAULT_FORMAT}" ;;
*) # Allright! Let's bang a gong and get it on! if [ ! -d "/proc" ] then echo -e "No proc filesystem found.\nCannot continue." exit 1 fi # calculator function function calc { # First test if $CALCEXE contains any information if not then set a # value. Is this a good (fast/efficient) way to do it? test -n "$CALCEXE" || CALCEXE=`which perl` || CALCEXE=`which bc` || CALCEXE="FAIL" case $CALCEXE in *perl) $CALCEXE -e "printf '%.${DECIMALS}f',${@}" ;; *bc) echo -e "scale=$DECIMALS\n${@}" | $CALCEXE ;; FAIL) echo -n "Could not calculate: excutable missing" exit 1 ;; esac } function addresult { # Search and replace marked places of OUTPUT FORMAT with # correcponding values. OUTPUT_FORMAT=`echo "$OUTPUT_FORMAT" | sed -e "s/-$1-/$2/g"` } if [ -n "$*" ] then ARGS="$*" else ARGS="." fi if echo $ARGS | grep "\-\-" > /dev/null then OUTPUT_FORMAT=${ARGS##*--} OUTPUT_FORMAT=${OUTPUT_FORMAT#* } if echo "$OUTPUT_FORMAT" | grep -v "\-*\-" > /dev/null then OUTPUT_FORMAT="." fi else OUTPUT_FORMAT=$ARGS fi if [ "$OUTPUT_FORMAT" == "." ] then OUTPUT_FORMAT="$DEFAULT_FORMAT" fi # Case-hell starts here.;P case $OUTPUT_FORMAT in *-UPTIME-*) UPTIME="" TOTSECS=`PROCUPTIME=$(cat /proc/uptime) && echo ${PROCUPTIME%%.*}` let "SECS=${TOTSECS}%60" let "MINS=${TOTSECS}/60%60" let "HOURS=${TOTSECS}/3600%24" if echo "$ARGS" | grep -i "\-\-uptimeweeks" > /dev/null then let "DAYS=${TOTSECS}/86400%7" let "WEEKS=${TOTSECS}/604800" else let "DAYS=${TOTSECS}/86400" fi if [ -n "$WEEKS" ] && [ "$WEEKS" != "0" ] then UPTIME="${UPTIME}${WEEKS}w" fi if [ "$DAYS" != "0" ] then UPTIME="${UPTIME}${DAYS}d" fi UPTIME="${UPTIME}${HOURS}h${MINS}m${SECS}s" addresult "UPTIME" "$UPTIME" ;; esac case $OUTPUT_FORMAT in *-IDLEPERCENT-*) DECIMALS="4" # This tests if PROCUPTIME is already set. # It already should have some value if user has requested -UPTIME- from # the command line if [ -z $PROCUPTIME ] then PROCUPTIME=`cat /proc/uptime` TOTSECS=${PROCUPTIME%%.*} fi # Parse and calculate IDLESECS=${PROCUPTIME#* } IDLESECS=${IDLESECS%.*} IDLEPERCENT=`calc $IDLESECS/$TOTSECS*100` IDLEPERCENT="${IDLEPERCENT}%" addresult "IDLEPERCENT" "$IDLEPERCENT" ;; esac
############################################################################ ### Memory related part - start ############################################ ############################################################################
function parsememinfo { # Get memory information if there isn't already test -z "$MEMINFO" && MEMINFO=`cat /proc/meminfo` PARSED=${MEMINFO#*$*:} PARSED=${PARSED%% kB*} # echo $PARSED } function memfree { parsememinfo "MemFree" MEMFREE=$PARSED parsememinfo "Cached" CACHED=$PARSED parsememinfo "Buffers" BUFFERS=$PARSED let "MEMFREE=${MEMFREE}+${CACHED}+${BUFFERS}" MEMFREERAW=$MEMFREE } function memsuffix { test -n "$MEMSUFFIX" || case $ARGS in *--mmega*) MEMSUFFIX="MB";; *) MEMSUFFIX="kB";; esac }
case $OUTPUT_FORMAT in *-MEMFREE-*) # Count free memory
# As far as I know anything about memory # egrep "^Cached:|^MemFree:|^Buffers:" /proc/meminfo # shows the actual free memory. # So this script will count the sum of those values memfree memsuffix test "$MEMSUFFIX" == "MB" && let "MEMFREE=$MEMFREE/1024" MEMFREE="${MEMFREE}${MEMSUFFIX}" addresult "MEMFREE" "$MEMFREE" ;; esac case $OUTPUT_FORMAT in *-MEMTOTAL-*) # Count total memory parsememinfo "MemTotal" MEMTOTAL=$PARSED memsuffix MEMTOTALRAW=$MEMTOTAL test "$MEMSUFFIX" == "MB" && let "MEMTOTAL=$MEMTOTAL/1024" MEMTOTAL="${MEMTOTAL}${MEMSUFFIX}" addresult "MEMTOTAL" "$MEMTOTAL" ;; esac case $OUTPUT_FORMAT in *-MEMUSAGE-*) # Count memory usage test -n $MEMFREERAW || memfree test -n $MEMTOTALRAW || parsememinfo MemTotal && MEMTOTALRAW=$PARSED let "MEMUSAGE=$MEMTOTALRAW-$MEMFREERAW" memsuffix test "$MEMSUFFIX" == "MB" && let "MEMUSAGE=$MEMUSAGE/1024" MEMUSAGE="${MEMUSAGE}${MEMSUFFIX}" addresult "MEMUSAGE" "$MEMUSAGE" ;; esac ############################################################################ ### Memory related part - end # CPU related part - start ################### ############################################################################ # function to parse /proc/cpuinfo function parsecpuinfo { # test -n "$TAB" || TAB=`echo -ne "\t"` # Get CPUinfo if we don't have it yet test -z "$CPUINFO" && CPUINFO=`cat /proc/cpuinfo` PARSED=`echo "$CPUINFO" | grep "$@"` PARSED=${PARSED##*: } # echo $PARSED } case $OUTPUT_FORMAT in *-CPUMODEL-*) parsecpuinfo "model name" addresult "CPUMODEL" "$PARSED" ;; esac case $OUTPUT_FORMAT in *-CPUSPEED-*) parsecpuinfo "cpu MHz" addresult "CPUSPEED" "${PARSED}MHz" ;; esac case $OUTPUT_FORMAT in *-BOGOMIPS-*) parsecpuinfo "bogomips" addresult "BOGOMIPS" "$PARSED" ;; esac case $OUTPUT_FORMAT in *-CPUCACHE-*) parsecpuinfo "cache size" addresult "CPUCACHE" "$PARSED" ;; esac
############################################################################ ### CPU related part - end ################################################# ############################################################################ # Finally echo all the requested statistics echo -e "$OUTPUT_FORMAT" ;; # Here it ends. esac |
Posted by mikshaw on Jan. 24 2008,22:29
I attempted to test it, but DSL doesn't have bc and I haven't bothered to install it.
I did get a little info, though: Uptime: 9h54m23s | Uptime load average: | Mem total/used/free: 515304kB/105724kB/409580kB
Posted by Zucca on Jan. 24 2008,22:43
You can customize how it outputs statistics. run it with --help. Anyway. I have developed it much. I want to finish it fast. ;) New version will be here soon. BTW. if DSL does not have bc, then is it possible to have decimals when calculating with "let"?
Here's a "shot" from new version:Quote | zucca@zelan ~/scripts/bash $ sh sysinfo.sh --help sysinfo.sh version 1.8b
USAGE: sysinfo.sh [--uptimeweeks] [--mmega] [OUTPUT FORMAT] USAGE: sysinfo.sh [--help]
OUTPUT FORMAT can have any text you like (sysinfo.sh will use echo with no argument to print information, so use your head.), but sysinfo.sh will replace following: -UPTIME- will show system uptime. --uptimeweeks will tell uptime in weeks if uptime is seven days or more. -UPTIMELA- will show load average of whole uptime (this may not be accurate) -CPUMODEL- diplays your CPU model -CPUSPEED- displays the clockspeed of your processor -CPUCACHE- shows size of your CPU cache -BOGOMIPS- see < http://en.wikipedia.org/wiki/Bogomips > -MEMTOTAL- will be replaced with amout of total physical (RAM) memory in your system -MEMUSAGE- same as above but displays used memory -MEMFREE- same as above but displays free memory
Note: switches can be in any order as long as they are before OUTPUT FORMAT
Example: sysinfo.sh -UPTIME- will show you uptime in days, hours, minutes and seconds.
If OUTPUT FORMAT does not contain any text it defaults to: Uptime: -UPTIME- | Uptime load average: -UPTIMELA- | -CPUMODEL- @ -CPUSPEED- | Bogomips: -BOGOMIPS- | Mem total/used/free: -MEMTOTAL-/-MEMUSAGE-/-MEMFREE- zucca@zelan ~/scripts/bash $ sh sysinfo.sh --mmega Uptime: 1d3h10m47s | Uptime load average: 0.3740 | Pentium III (Coppermine) @ 896.126MHz | Bogomips: 1793.84 | Mem total/used/free: 499MB/290MB/209MB |
Posted by curaga on Jan. 25 2008,22:52
Quote | is it possible to have decimals when calculating with "let"? | Nah
Posted by WDef on Jan. 26 2008,01:21
Hi Zucca
Suggestions:
1. You can use the -q option to grep to shut it up rather than redirecting to /dev/null all the time.
2. You might want to investigate the use of "case" instead of repeatedly parsing the arguments which is inefficient (or use getopts).
3. Command substitution using Perl or awk are easy ways to do floating point arithmetic (ie decimals) in a shell script - there's no need to resort to bc (but everyone seems to forget this and pull out bc).
eg .. say I want to add 1.35 to 6.78 and divide by 9.1 and these numbers are in shell vars a,b,c respectively, and I want to put the result in var d:
Code Sample | d=$(echo "$a $b $c" | awk '{printf ($1 + $2 )/ $3 }') |
echo $d gives 0.913187
To round to 2 dec places:
Code Sample | d=$(echo "$a $b $c" | awk '{printf "%1.2f", ($1 + $2 )/ $3 }') |
Or doing a similar command substitution using Perl (no echo needed):
Code Sample | d=$(perl -e "print (($a + $b) / $c)") |
To round to 2 dec places:
Code Sample | d=$(perl -e "printf '%.2f', (($a + $b) / $c)") |
echo $d yields:
0.91
Look up printf to understand the precision modifier (number of dec places).
No bc needed!
Posted by ^thehatsrule^ on Jan. 26 2008,01:55
1. fyi, from grep man page:
Quote | Suppress error messages about nonexistent or unreadable files. Portability note: unlike GNU grep, traditional grep did not conform to POSIX.2 , because traditional grep lacked a -q option and its -s option behaved like GNU grep's -q option. Shell scripts intended to be portable to traditional grep should avoid both -q and -s and should redirect output to /dev/null instead. |
Posted by WDef on Jan. 26 2008,02:00
Does this script need to run on non-GNU systems?
Posted by Zucca on Jan. 27 2008,21:02
Well I have one friend who might want to test this on Mac OS X. I don't know even if OSX has the /proc filesystem... Anyway first priority is to get this working on Linux with minimal depencies.
Posted by humpty on Jan. 28 2008,16:54
it doesn't look like you actually need the decimal places, you can probably get away with just integer arithmetic; i.e secs=`expr $totalsecs / 60`
Posted by Zucca on Jan. 28 2008,17:50
I don't need it there. I will need decimals where I calculate percentual value of non-idle time from uptime (that will replace -UPTIMELA-). Perl seems to be quite neat solution anyways.
I just came from dentist and half of my face is numb... Also my thinking is at least 10 times slower... I'll be back again tomorrow. ;)
Posted by Zucca on Jan. 29 2008,13:54
Some improvements
I'm currently replacing as many if+grep combinations as possible with case statement, but is there a way to make case go trough _every_ <pattern>) <code to execute> that meets the criteria? Here's an example:
Code Sample | PATTERN="one two three" case $PATTERN in *one*) echo "One matched";; *two*) echo "Two matcched";; *three*) echo "Three matched";; esac |
Now it only echoes "One matched". I would like it to echo all of those. Any way possible with _one_ case statement?
And I impoved calculation a bit with a nice function:
Code Sample | # calculator function function calc { # First test if $CALCEXE contains any information if not then set a # value. Is this a good (fast/efficient) way to do it? test -n "$CALCEXE" || CALCEXE=`which perl` || CALCEXE=`which bc` || CALCEXE="FAIL" case $CALCEXE in *perl) $CALCEXE -e "printf '%.${DECIMALS}f',${@}" ;; *bc) echo -e "scale=$DECIMALS\n${@}" | $CALCEXE ;; FAIL) echo -n "Could not calculate: excutable missing" exit 1 ;; esac } |
I think it's quite lightweight. I would like to add awk also there if it can calculate same way as perl and bc. I read somewhere that awk is more common on *NIX systems than perl or bc. Only basic calculation operators are needed: + - * and /, plus decimal support. I would also like to replace sed with awk if it can perform search & replace easily, like sed. So anyone who knows awk, please tell. =)
Posted by mikshaw on Jan. 29 2008,15:29
Quote | Now it only echoes "One matched". I would like it to echo all of those. Any way possible with _one_ case statement? | Case doesn't work that way. It compares the string to each option in order, and stops when it finds a match.
You can accomplish what you need in a loop:
Code Sample | for i in $PATTERN; do case $i in one) echo "One matched";; two) echo "Two matched";; three) echo "Three matched";; esac done | This may not be the most efficient way, but it should work.
Posted by Zucca on Jan. 29 2008,16:47
Quote (mikshaw @ Jan. 29 2008,12:29) | You can accomplish what you need in a loop:
Code Sample | for i in $PATTERN; do case $i in one) echo "One matched";; two) echo "Two matched";; three) echo "Three matched";; esac done | This may not be the most efficient way, but it should work. |
Well I think many case-sentences in a row might be more efficient. But I could test it with time command. =)
Posted by Zucca on Jan. 29 2008,17:17
Results
I tested with this bash code:Code Sample | echo "With for -loop" time for i in $@ do case $i in 1) echo 1;; 2) echo 2;; 3) echo 3;; 4) echo 4;; 5) echo 5;; 6) echo 6;; 7) echo 7;; 8) echo 8;; 9) echo 9;; ten) echo ten;; esac done
echo "Cases in a row" time ( case $@ in *1*) echo 1;; esac case $@ in *2*) echo 2;; esac case $@ in *3*) echo 3;; esac case $@ in *4*) echo 4;; esac case $@ in *5*) echo 5;; esac case $@ in *6*) echo 6;; esac case $@ in *7*) echo 7;; esac case $@ in *8*) echo 8;; esac case $@ in *9*) echo 9;; esac case $@ in *ten*) echo ten;; esac )
|
And here's when I ran it:Quote | $ sh test.sh 1 2 3 4 5 6 7 8 9 ten With for -loop 1 2 3 4 5 6 7 8 9 ten
real 0m0.006s user 0m0.000s sys 0m0.000s Cases in a row 1 2 3 4 5 6 7 8 9 ten
real 0m0.007s user 0m0.000s sys 0m0.000s |
I have to say that I was a bit surprised. =) I ran that many times. Times got a bit different each time, but for loop+case won each time.
I need open several other processes to make CPU more busy to get more accurate results.
Edit: Ok. There was no singnificant difference. Maybe lowering clockspeed will show more...
Posted by ^thehatsrule^ on Jan. 29 2008,17:29
Quote | I have to say that I was a bit surprised. =) I ran that many times. Times got a bit different each time, but for loop+case won each time. | That's not too surprising actually... in your many cases script it continously passes all the arguments and looks through all of them each time, whereas the for loop implementation doesn't have wildcards in the case statement and only compares one parameter at a time. And having a loop like that seems to be pretty common to me.
Quote | I would also like to replace sed with awk if it can perform search & replace easily, like sed. | I'd stick with sed because it should be a 'lighter' binary (unless you have some reason to worry about having a missing sed)
Also, if you can, avoid using search and replace at all if possible. For example, looking at your code in your first post, you can make a function that can print the output from variables instead of replacing the text in OUTPUT_FORMAT.
Posted by Zucca on Jan. 29 2008,18:23
Quote (^thehatsrule^ @ Jan. 29 2008,14:29) | Quote | I would also like to replace sed with awk if it can perform search & replace easily, like sed. | I'd stick with sed because it should be a 'lighter' binary (unless you have some reason to worry about having a missing sed)
Also, if you can, avoid using search and replace at all if possible. For example, looking at your code in your first post, you can make a function that can print the output from variables instead of replacing the text in OUTPUT_FORMAT. |
Yes. Just because of that. I've read that awk is more common than sed. From Wikipedia: Quote | A version of the AWK language is a standard feature of nearly every modern Unix-like operating system available today. | Quote | Besides the Bourne shell, AWK is the only other scripting language available in a standard Unix environment. |
But now when you said that sed is lighter, I'll plan my script primary to look for sed, and then awk. =)
About for+case: I think I have to stick with multiple cases. If I pass OUTPUT_FORMAT for for -loop to go trough and then if/when sed/awk modifies it (still insife for -loop), for -loop won't know it's been modified. Right? Then case inside for -loop might have to modify same information, bit in different place (in OUTPUT_FORMAT), more than once. Ok. Cituation like this is rare.Possible only is user has specified same spot (-UPTIME- for example) more than once. With many case -sentences OUTPUT_FORMAT is modified instantly if any of the case -sentences is triggered.
Anyway tests that I performed showed very little difference, so I think this "performance tweaking" with for-case vs. many cases isn't really relevant anymore. I'd like to focus more to make this script to work on as many platforms/OSes as possible, meaning to make this use most common UNIX tools awailable.. ;) Many thanks anyway.
And I will need the search and replace because user running this script can specify his/her own output from the command line ie: ./sysinfo.sh "Uptime: -UPTIME- | Free RAM: -MEMFREE-" Basically sed (maybe awk also) is there to search & replace user defined command line arguments.
Get it? ;)
Ok. Enough long post already. Brb going to moon.
Posted by ^thehatsrule^ on Jan. 29 2008,19:05
Quote | And I will need the search and replace because user running this script can specify his/her own output from the command line ie: ./sysinfo.sh "Uptime: -UPTIME- | Free RAM: -MEMFREE-" Basically sed (maybe awk also) is there to search & replace user defined command line arguments. | How often are you going to use those custom lines? If you really want to be somewhat more efficient you could only use sed/awk when you have custom lines instead (or somehow specify and eval given variables on the command line?). It really depends on how much you want to spend on this.
Posted by Zucca on Jan. 29 2008,19:39
That's true. It would be more efficient that way. It may be a bit complex to implement, but I'll try it some time. =)
Posted by Zucca on Jan. 29 2008,20:07
New relase
Some if+grep statements still need to change. And as usual, comments and suggestions are very welcome. ;)
< Go to first post to get it >
Posted by Zucca on Jan. 30 2008,13:04
Bug spotted. It does not result to any error. But as I ran that script with bash -x I could see how it uses cat to get information from /proc even if specific information is already there. It makes this script slower. Even I have code to check if script already has the information needed, it still goes to fetch the information again. Here's an example code where it fails to regonize that the data is already there:Code Sample | function parsememinfo { # Get memory information if there isn't already if [ -z "$MEMINFO" ] then MEMINFO=`cat /proc/meminfo` fi PARSED=${MEMINFO#*$*:} PARSED=${PARSED%% kB*} echo $PARSED } |
Any of you have any solution to this? First the code was like this: test -z $VARIABLE && VARIABLE="data" and it didn't worked any better than the code above.
Posted by curaga on Jan. 30 2008,17:22
I read somewhere that some versions of bash can only use -z with number variables.
Try:
if [ ! -n "$MEMINFO" ]
aka not not null.
Posted by ^thehatsrule^ on Jan. 30 2008,17:23
I think that's because $() uses a subshell in order to execute the command substitution... so the variable is lost afterwards.
Since you really only need to read that file once, the easiest change would be to read it before you call that function.
EDIT: saw previous post:
Quote | I read somewhere that some versions of bash can only use -z with number variables.
Try:
if [ ! -n "$MEMINFO" ]
aka not not null. | You mean for test, not bash..? Also, -z is for strings only (and if it wasn't, an error would be printed). For the most portability, = should be used iirc.
Posted by WDef on Jan. 30 2008,23:52
Zucca: re using awk to do real arithmetic - I thought I did show you how to - go back and re-read my post, the same one with Perl.
Perl vs Awk: a *nix system without Perl is rare indeed.
Re: sed vs awk. The usual rule is you try to avoid sed for anything except simple replacements, which it is usually best for. But really, it doesn't much matter on modern processors unless an operation is in a lengthy loop or is otherwise chewing up a lot of resources.
Posted by mikshaw on Jan. 31 2008,00:30
I think the only thing I've ever used sed for was replacement. I don't even know what else it does =o)
Posted by Zucca on Jan. 31 2008,15:06
Quote (^thehatsrule^ @ Jan. 30 2008,14:23) | I think that's because $() uses a subshell in order to execute the command substitution... so the variable is lost afterwards. |
But I don't have any "$(command)" there. I read that to set the variable local only you must use local -command.
But if it is really lost somewhere, is there a way to pass it to the outer process?
Posted by ^thehatsrule^ on Jan. 31 2008,16:58
Quote (Zucca @ Jan. 31 2008,10:06) | Quote (^thehatsrule^ @ Jan. 30 2008,14:23) | I think that's because $() uses a subshell in order to execute the command substitution... so the variable is lost afterwards. |
But I don't have any "$(command)" there. I read that to set the variable local only you must use local -command.
But if it is really lost somewhere, is there a way to pass it to the outer process? |
Well, `` does the same thing as $() or maybe you weren't looking where parsememinfo was being called (in the memfree function)?
It's not local variables that you are looking at right now... it's the child subshell(?) that cannot pass a variable (directly) to a parent - hence my original suggestion.
Posted by Zucca on Jan. 31 2008,17:37
Ok. I think now how I will manage this problem...
Posted by WDef on Feb. 01 2008,01:38
The easiest way to get a variable value out of a command substition is to echo it into a variable.
Say I have a function func that produces a result in variable RES, and I call func via command substitution (hence in a subshell). I can get RES into ANSWER this way:
Code Sample | func(){ # blah RES=5 echo $RES }
ANSWER=$(func)
|
In long messy scripts, this can be a good way to pass variables out of functions without getting mixed up global variables. Klaus Knopper does this all the time.
Note anything written to stdout from func will go into ANSWER, not to the terminal.
If you need something in func to go to the terminal and not go into ANSWER, re-direct that line's stdout to /dev/tty
Posted by Zucca on Feb. 04 2008,21:28
New version.
I made it faster by modifying functions. Those who like to test it will find it from < here >.
As always, bug reports are welcome. =)
|