Valerie Aurora ([info]valhenson) wrote,
@ 2008-12-03 18:05:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:programming

bash lesson of the day
So I'm running a command in a for loop in bash:

SECONDS=1
for i in 1 2 3 4; do
    ../my_test -S "${SECONDS}"
done
And for some damn reason, the test runs for 1 second on the first loop, then 2 seconds on the second loop, then 4 seconds on the next, etc. WTF?

Ten minutes of debugging output later, I finally type "man bash":

  SECONDS
    Each time this parameter is referenced, the  number  of  seconds
    since  shell  invocation is returned.  If a value is assigned to
    SECONDS, the value returned upon subsequent  references  is  the
    number  of seconds since the assignment plus the value assigned.
    If SECONDS is unset, it loses its special properties, even if it
    is subsequently reset.
Geez.




(Post a new comment)


[info]two_pi_r
2008-12-04 02:41 am UTC (link)
That's cute.

(Reply to this)


[info]gomijacogeo
2008-12-04 03:13 am UTC (link)
The "unset to lose special properties" is a common mechanism in bash. Some scripts will attempt to future-proof themselves by explicitly unsetting all their vars at the very beginning before using them. I just try to stick to lower case.

(Reply to this) (Thread)


[info]valhenson
2008-12-04 05:19 am UTC (link)
I think you may have missed the point - I was using SECONDS as a regular ol' variable and was totally unaware that it was a special builtin varialbe.

(Reply to this) (Parent)(Thread)


[info]valhenson
2008-12-04 05:20 am UTC (link)
Ah, okay, maybe you didn't miss the point. :)

(Reply to this) (Parent)(Thread)


[info]gomijacogeo
2008-12-04 06:09 am UTC (link)
Yeah, I'd like to think I got it at least.

I was, without explicitly stating, moving on from the "ya got bit in an interesting way" to "how do some people avoid getting bit again" because being bit the 2nd time is almost never interesting.

One way would be to memorize the list of magic bash variables and hope more don't get added. Way two was the clear em all as just a rote programming style. Way three was to hopefully avoid the namespace altogether and hope they never intrude.

I learned the lesson from the other direction. I was reading a script and wondered why the heck someone went through all the trouble of unsetting every variable.

P.S. Hello. I'm John. I do Infiniband driver development. Decided to follow your blog because of the occasional nifty links and git ponderings.

(Reply to this) (Parent)(Thread)


[info]kmhoofnagle
2008-12-04 02:23 pm UTC (link)
*this* is the tidbit I needed. I do bash work just often enough to know bash without having a thoughtful best-practices sort of approach.

(Reply to this) (Parent)


[info]thargol
2008-12-04 09:06 am UTC (link)
But why was it in upper case, then (which by convention is reserved for environment variables)? I'd assumed you were deliberately aiming for the special variable, purely because of the upper case. If you'd wanted a shell variable, then use lower case. In this case, it would even have prevented the problem (albeit more by luck than judgement!)

(Reply to this) (Parent)


(Anonymous)
2008-12-04 04:06 am UTC (link)
Ah, magic shell variables. I vaguely recall being bitten by something like that in the past - like Gomijacogeo, I tend to avoid upper-case variable names as a result.

(Reply to this)

Great topic
[info]infinitefuture.blogspot.com
2008-12-08 02:53 pm UTC (link)
That was interesting and the comments were as well. It is nice that you have a blog now. I was not convinced and so I wrote this to see what happened. Then I read man bash and accepted it. I see errors in the manuals even now as "man" is not always well maintained. #!/bin/bash SECONDS=1 for (( i=1; $i <= 10; i++ )) do sleep 2 echo $i,"${SECONDS}" done

(Reply to this)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…