Idle time perl script bug?

Hi,

When I run this script:


set idle_time to 0
repeat until idle_time > 300
	try
		set idle_time to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'")
		say (idle_time as string) without waiting until completion
		delay 10
	on error err_msg
		display dialog err_msg
		exit repeat
	end try
end repeat
idle_time

it stops at 40 seconds. If I change to “repeat until idle_time > 100” it goes to 20 seconds. Under 90 seconds it works. Anyone know what is happening.

BTW, the awk and sed versions work. Here’s the awk:


set idle_time to 0
repeat until idle_time > 300
	try
		-- took out int from int{print ($NF/1000000000)
		set idle_time to (do shell script "ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print ($NF/1000000000); exit}'") as real
		say (idle_time as string) without waiting until completion
		delay 10
	on error err_msg
		display dialog err_msg
		exit repeat
	end try
end repeat
idle_time

Thanks,

Model: MacBook Pro
AppleScript: 2.2.3
Browser: Safari 536.26.17
Operating System: Mac OS X (10.8)

THis seemed to have fixed it:


set idle_time to 0
repeat until idle_time > 300
	try
		set idle_time to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'") as real
		say (idle_time as string) without waiting until completion
		delay 10
	on error err_msg
		display dialog err_msg
		exit repeat
	end try
end repeat
idle_time

I added “as real” to the “set idle_time” line. Something to do with the length of the numbers I think. Not sure.

Where do you live Kel?

The idle commands doesn’t work on my machine because in US we’re using 1,000.00 notation while my mac uses 1.000,00 number notation. This notation settings in system preferences are used in AppleScript too which makes the common idle time handler not work on my machine. When you do to a real conversion the 0.02 idle time is coerced to 20 with my localization settings on my machine.

"0.0237829" as integer --> 237829 
"0.0237829" as real --> 2.37829E+5
"0,0237829" as integer --> 0
"0,0237829" as real --> 0.0237829

So what I’m using to get proper idle time no matter what location settings you have I use:

set idleTime to ((do shell script "ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print ($NF); exit}'") as integer) / (1000 ^ 3)

Hi DJ Bazzie Wazzie,

I’ve never heard about using commas as decimal. When I run your coercion script, i get an error: Can’t make "0,0237829" into type integer." number -1700 from “0,0237829” to integer.

I’m in Hawaii, but don’t know what that has to do with it. One thing I’ve noticed about this new system is that they link us with Aleutian Islands.

I’ll use your universal script.

Thanks,

Funny that you’ve never heard of it. because more than half of the world is using a comma as decimal mark instead of point/period. Well the code I posted was to test which decimal mark you had. But when you said you come from Hawaii, it was already obvious that you don’t have the same problem as I do. However I would go for my version of idle time if you ever start thinking to distribute your code.

I am not sure who deviced this, but I have seen it in a lot of posts here:


set decSep to character 2 of ((1 / 10) as text)
if decSep is "," then
	set thouSep to "."
else
	set thouSep to ","
end if

The thing is, you can’t really trust it when it comes to tools, but you can probe awk for instance, that resides in /usr/bin, you may have to switch decimal and thousands separators back and forth to get it right. When it comes to perl, I guess you’ll have to device some kind of scheme like that as well.

It reminds me of the time when I never heard about people using the YYMMDD format in every day life.

I just tried the awk method that I posted earlier, without the “as real” coercion and it cycled 2 times and stopped.

I wonder why unix is using commas for decimal places on my system. Is there a setting somewhere to change that?

Thanks,

Well in this case they’re looking up for an integer (nanoseconds) that they divide with AWK, return to AS and coerce that string into a real. My suggestion is that they return the integer from AWK to AS, coerce the returned string it into an integer and then divide it in AS. This way you don’t have to worry about string to real coercions because there isn’t.

I can imagine that there are situations you can’t return an integer from the shell and returned string needs to coerced into a number. Then when there is no other possibility, I would use run script command. Because a real always uses a decimal point and never a decimal comma you can use a run script for returned numbers from the shell.

"0.5" as real --> behaves differently depending on the decimal mark
run script "0.5"  --> will always return a real 0.5

To coerce the returned string into a real not matter which system settings, you can use:

run script (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'")

Some commands respects the locale settings in UNIX while other won’t. However the locale setting for do shell scripts use a shell environment other than Terminal.app and the locale setting is by default “C”. This means that it uses a decimal point and thousand comma and not visa versa.

So are you sure that AWK and Perl both uses decimal comma instead of decimal points? Because that wouldn’t make any sense… If it’s true you should definitely use my first suggestion:

set idleTime to ((do shell script "ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print ($NF); exit}'") as integer) / (1000 ^ 3)

I like your idea about just returning the integer. Reading the tutorials on awk, much less than perl, is too hard for me at the moment. :o All I have to do is get rid of the /1000000000. Then, just do it in AppleScript. Good solution and easy solution. YOu saved me a lot of time.

Thanks a lot,