Results 1 to 9 of 9

Thread: bash shell - problem assigning expression to variable

  1. #1
    Join Date
    May 2013
    Beans
    3

    bash shell - problem assigning expression to variable

    Hi guys

    I am having some troubles to get my bash script working. Process assigned to that script stop as soon as I start it.
    After some tests, I identify that something wrong is happening into following lines :
    Code:
     USR=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 2 | cut -d'%' -f 1 | cut -d'.' -f 1)
     SYS=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 3 | cut -d'%' -f 1 | cut -d'.' -f 1)
    
    
     ALL=$(($USR+$SYS))
     echo $ALL | tr '[ \n]' '-' >> stat.log
    I try to assign to variables USR and SYS some expressions. I think that my syntax is correct but at the end it is not working.

    It tried that way too :
    Code:
     USR=`top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 2 | cut -d'%' -f 1 | cut -d'.' -f 1`
     SYS=`top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 3 | cut -d'%' -f 1 | cut -d'.' -f 1`
    But result is the same.

    Does somebody have an idea what I am doing wrong here?
    I suspect an issue with some wrong quotes used but after some search I don't find any solution...



    UPDATE 19/05 :
    The script is basically running when I start it on the current thread :
    Code:
     
    stou@laptop:~/$ sh read_stats.sh
    But my problem is when I start it on another thread to let it work in background. It stops as soon as I tip another command (or just press ENTER) in shell :
    Code:
     
    stou@laptop:~/$ sh read_stats.sh &
    [1] 4473
    stou@laptop:~/$
    [1]+  Stopped          sh read_stats.sh
    stou@laptop:~/$
    Last edited by stou; May 19th, 2013 at 10:04 AM. Reason: additional info

  2. #2
    Join Date
    Oct 2011
    Location
    ZZ9 Plural Z Alpha
    Beans
    Hidden!
    Distro
    Ubuntu

    Re: bash shell - problem assigning expression to variable

    One problem you have is with using the variable $USER. That it is a system reserved variable, for printing the name of the current (you guessed it) user. Rename the variable $USR or something else.
    Might be a good idea to check with printenv to make sure you're not trying to overwrite any environment variables.

  3. #3
    Join Date
    May 2013
    Beans
    3

    Re: bash shell - problem assigning expression to variable

    Hi cortman,

    Thanks for your tip
    It's kind of a stupid issue... So I changed USER variable to USR (and checked with printenv for other potentially reserved variable names I maybe override).

    Unfortunately the result is the same with this new variable name...

    Does anyone has another idea?

    (I updated my initial message as I got some others informations during my tests)

  4. #4
    Join Date
    Apr 2012
    Beans
    5,386

    Re: bash shell - problem assigning expression to variable

    It's difficult to tell from just the fragment you provided, but I think the problem is possibly not the variable assignment, but that 'top' doesn't like running without an interactive shell e.g.

    Code:
    $ top > top.out &
    [3] 16383
    $ 
    
    [3]+  Stopped                 top > top.out
    $ kill 16383 
    $ ls -l top.out
    -rw-rw-r-- 1 steeldriver steeldriver 0 May 19 07:30 top.out
    You can try giving the -b (batch mode) flag to top e.g.
    Code:
    $ top -b > top.out &
    [4] 16391
    $ 
    $ kill 16391
    $ 
    [4]-  Exit 143                top -b > top.out
    $ ls -l top.out
    -rw-rw-r-- 1 steeldriver steeldriver 62071 May 19 07:32 top.out
    $

  5. #5
    Join Date
    Mar 2008
    Beans
    1,219

    Re: bash shell - problem assigning expression to variable

    Quote Originally Posted by stou View Post
    Code:
     USR=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 2 | cut -d'%' -f 1 | cut -d'.' -f 1)
     SYS=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 3 | cut -d'%' -f 1 | cut -d'.' -f 1)
     ALL=$(($USR+$SYS))
    ^ Are you trying to get the integer part of us and sy here? Well, how about:
    Code:
    cpu_usage=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1)
    cpu_sys_usr=$(echo ${cpu_usage#* } | awk -F'[,. ]' '{ print $1, "+", $4 }')
    cpu_all=$(expr $cpu_sys_usr)
    then?

    Re. your script as a whole, I have a gut feeling that you're trying to reinvent nice or time. And you probably shouldn't do that. :)
    Last edited by prodigy_; May 21st, 2013 at 04:34 AM.

  6. #6
    Join Date
    Feb 2013
    Beans
    Hidden!

    Re: bash shell - problem assigning expression to variable

    Quote Originally Posted by stou View Post
    Code:
    SYS=$(top -d1 -n2 | grep 'Cpu(s)' | tail -1 | sed -e 's/\s\+/ /g' | cut -d' ' -f 3 | cut -d'%' -f 1 | cut -d'.' -f 1)
    The 3 there most probably should be 4.

    But I'd rather parse the output of vmstat
    Code:
    cpu_all=$(vmstat 1 2|awk 'NR>3{print $13+$14}')
    Last edited by schragge; May 19th, 2013 at 04:39 PM.

  7. #7
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,323
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: bash shell - problem assigning expression to variable

    as for all-caps names - simply don't use them. There is a boatload of env variables that are all-caps by convention. I've seen someone override PATH, long story short the results were not pretty (all commands stopped to work because shell couldn't locate them anymore). Have at least 1 lowercase char and you won't risk overriding them ever again.
    Last edited by Vaphell; May 19th, 2013 at 05:14 PM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  8. #8
    Join Date
    Oct 2011
    Location
    ZZ9 Plural Z Alpha
    Beans
    Hidden!
    Distro
    Ubuntu

    Re: bash shell - problem assigning expression to variable

    It is also often useful to run a script in debugging mode, with the -x option.

  9. #9
    Join Date
    May 2013
    Beans
    3

    Re: bash shell - problem assigning expression to variable

    Hi guys

    Thanks a lot for your answers!
    My original problem here was what @steeldriver pointed out : I used top command not in batch mode.
    Then I tried with -d option. It is working but it seems not very proper in my case as I want to launch a shell script and let it run for a long period (logging some statistics over cpu, memory and network use). Top outputs seems not very stable to parse.

    I will rather use the vmstat command outputs like @schragge advised. I didn't know that command

    Unfortunately to run the script in debugging mode was not useful in my case because that was not a syntax or logic problem but an execution issue (top not working normally when I started the script in background). Is it possible to start a background process in debugging mode?

    @Vaphell I am already following your advice -> no more all-caps variable names in my shell scripts!

    You can turn that thread as solved, thanks guys!
    Last edited by stou; May 20th, 2013 at 03:07 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •