I am programming an app to synchronize some files with my NAS. Therefore I have to find out whether the program has been started via autostart or manually by the user. In the case of manual start it should present a dialog with some options, in case of autostart it should run with predefined parameters.
Assuming NAS refers to network-attached storage, and that your app would present the Dialog to the user if the user started the app by double-clicking its icon (rather than by an alternative unspecified scheduler), it seems to me that you don’t have much hope. An app doesn’t know how it was started.
Well you can check if the user is different when it is launched.
By default the Finder will launch an application with the user that is currently logged in. When an application is scheduled in launchd and it will be launched, it can be launched as another user. So you could check here…
I found a way to determin what the program should do depending on autostart or manual start:
One of the first steps in the program is to read some data from a file. Hence, I can compare the date and time of last access to that file and compare it with the system uptime. If the file access is longer ago than system uptime, it is the first time the program runs since start, so it must be autostart. If the other way round, it is manual start and the program should offer an option dialog.
script do determine uptime:
set UT to (do shell script "uptime")
-- set UT to "12:37 up 4 days, 3:54, 2 users, load averages: 0.24" as text
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set now to text item 1 of UT
set AppleScript's text item delimiters to "up"
set UpT to words 1 thru 6 of text item 2 of UT
set AppleScript's text item delimiters to TID
tell UpT
if "sec" is in (item 2 of UpT) or ("min" is in (item 2 of UpT) and "day" is not in (item 2 of UpT)) then
set msg to item 1 & space & item 2
else if "user" is in (item 4 of UpT) then
set msg to item 1 & " hours, " & item 2 & " mins"
else if "day" is in (item 2 of UpT) then
if "sec" is in (item 4 of UpT) or "min" is in (item 4 of UpT) or "hour" is in (item 4 of UpT) then
set msg to item 1 & space & item 2 & ", " & item 3 & space & item 4
else
set msg to item 1 & space & item 2 & " ," & item 3 & " hours, " & item 4 & " mins"
end if
end if
end tell
display dialog "At " & now & " this system has been up for" & return & msg buttons {"OK"} default button 1 with title "System Uptime"
Script to determine last file access:
set TheFile to quoted form of (POSIX path of (choose file))
set ATime to (do shell script "stat " & TheFile)
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set AcTime to words 18 thru 23 of ATime
set AppleScript's text item delimiters to TID
set AccessTime to ((item 2 of AcTime) & ":" & (item 3 of AcTime) & ":" & (item 4 of AcTime) & ", " & (item 1 of AcTime) & "." & (item 6 of AcTime) & "." & (item 5 of AcTime))
display dialog "Last access to file: " & AccessTime buttons {"OK"} default button 1 with title "Last File Access"
The scripts are not yet completelly finished, but they are the basis to compare these data.
???
I don’t understand. The man page of state tells me that the option -f allows to change format of the output somehow, but the format of the output is not the problem. The point is, the information I need is not in the output of stat.
And your command “stat -f %a ” gives me only a number: 1325002609
I have no idea what this number is…
I said it will output the epoch time (seconds from jan 1 1970 00:00:00). You can use this to put it in any kind of format if you like. Use %Sa to print with strftime format like date utility does. When no format is given to stat it uses it default format and that one doesn’t contain access times.
You wrote:
I thought I give you an example how to print out the last access time.
Can’t be correct. 1. January 1970 00:00:00 plus this number as seconds gives me a date in 1987. I am pretty shure at that time I did not yet have an iMac and that I accessed the file today…
Edit: It makes a difference wheather the output is added as a number or as a text. As number it is correct.
but anyway, it gives me the number the file was saved last time, that I can also get with my script above. But I need the date and time the file was opened last time, without saving or modifiying it.
Edit: o.k., problem solved. clicking it in the Finder to view the information about the file within the finder window is taken as an access, even if the file was not opened actually. But it helps, my orignial script will work that way.
adding 1325002609 seconds to 1 January 1970 00:00:00 is according to my calculations di 27 dec 2011 17:16:49. so you’re doing something wrong with your calculation. But you’ve already corrected that
It is correct! Don’t let the finder fool you, the file information you see there is not accurate at all. It’s one of the ‘wierd and odd’ things the finder does. It represents a value from it’s meta database and not an actual access time.
But if you want to use the finder info you should use mdls to get the kMDItemLastUsedDate meta data from the file instead of using the precise stat utility.
EDIT:
So you were looking for the inaccurate Finder info, like I said mdls would be the tool for you then.
I realised the difference in the same moment you wrong me the answer. And about the difference, I wrote above, it makes a difference whether the output of stat -f %a is stored and added as text or as number. At least in my script…
I can image that the as number/as text gives you different result because such a huge number (at least as integer) will be converted to an exponential number.
The output of stat -f %a changes also if I click the file in the finder.
I compared the two outputs with following scripts and it gave me no difference in the two outputs (except the one hour because of our time zone in Switzerland):
set TheFile to quoted form of (POSIX path of ("Macintosh HD:iTunes LastSync.txt"))
set ATime to (do shell script "stat " & TheFile)
set BTime to (do shell script "stat -f %a " & TheFile) as number
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set AcTime to words 9 thru 17 of ATime
set AppleScript's text item delimiters to TID
set AccessTime to ((item 2 of AcTime) & "." & (item 1 of AcTime) & "." & (item 6 of AcTime) & " " & (item 3 of AcTime) & ":" & (item 4 of AcTime) & ":" & (item 5 of AcTime))
display dialog "Last access to file: " & return & AccessTime & return & ((date "Donnerstag, 1. Januar 1970 00:00:00") + BTime + 3600) & return & (current date) buttons {"OK"} default button 1 with title "Last File Access"
o.k., now I got the solution for my problem: determine whether started via autostart or manual for a program what access a file in one of the first steps (in case the computer is conigured to german):
set Jetzt to current date
set UT to (do shell script "uptime")
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "up"
set UpT to words 1 thru 6 of text item 2 of UT
set AppleScript's text item delimiters to TID
tell UpT
if "sec" is in (item 2) then
set StartTime to ((Jetzt) - (item 1))
else if "min" is in (item 2) then
set StartTime to ((Jetzt) - ((item 1) * minutes))
else if "h" is in item 2 then
set StartTime to ((Jetzt) - ((item 1) * hours))
else if "user" is in (item 4) then
set StartTime to (Jetzt - ((item 1) * hours) - ((item 2) * minutes))
else if "day" is in (item 2) then
if "sec" is in item 4 then
set StartTime to (Jetzt - ((item 1) * days) - (item 3))
else if "min" is in item 4 of UpT then
set StartTime to (Jetzt - ((item 1) * days) - (item 3) * minutes)
else
set StartTime to (Jetzt - ((item 1) * days) - (item 3) * hours) - ((item 4) * minutes)
end if
end if
end tell
set TheFile to quoted form of (POSIX path of ("Macintosh HD:iTunes LastSync.txt"))
set ATime to (do shell script "stat " & TheFile)
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set AcTime to words 9 thru 17 of ATime
set AppleScript's text item delimiters to TID
if item 1 of AcTime is "Mar" then
set item 1 of AcTime to "Mär"
else if item 1 of AcTime is "May" then
set item 1 of AcTime to "Mai"
else if item 1 of AcTime is "Oct" then
set item 1 of AcTime to "Okt"
else if item 1 of AcTime is "Dec" then
set item 1 of AcTime to "Dez"
end if
set AccessTime to date ((item 2 of AcTime) & ". " & (item 1 of AcTime) & ". " & (item 6 of AcTime) & " " & (item 3 of AcTime) & ":" & (item 4 of AcTime) & ":" & (item 5 of AcTime))
if StartTime < AccessTime then
display dialog "Autostart ja"
else if StartTime > AccessTime then
display dialog "Autostart nein"
else
display dialog "Beide Zeiten gleich"
end if
Here is the same result with less code (I’ve missed your second post),
set upTime to do shell script "ps -p1 -o lstart | tail -1 | sed -e 's/ *$//'"
set upTime to do shell script "date -j -f %c +%s " & quoted form of upTime
set lastAccesTime to do shell script "stat -f %a /iTunes LastSync.txt"
set fileAccessed to (upTime as integer) < (lastAccesTime as integer)
fileAccessed is a boolean whether the file has been accessed during this OS session or not. The chance that the file will be accessed in the same second as the system start launching is nil.
@everyone who want to use this code: The access time is the time the file was last opened. Logically the Finder will open a file to show a preview, quicklook or other file information. This means that without opening a file by it’s editor it still can be opened by many other application like the Finder.
DJ Bazzie Wazzie, my program works now for like 99% of all scenarios at home. But I made a thinking failure. It works when the computer is restarted, but not if a user only logged of and logs in again.
Can the first line in your script be changed to determine login time instead of start time of the machine? Could you tell me how?
set upTime to do shell script "ps -axc -o comm,lstart | grep '^loginwindow' | awk '{print $2, $3, $4, $5, $6}'"
What I do is getting the upTime of the process ‘loginwindow’. It’s the first process that is launched after a user logs in. I thought that using the Finder or Dock for example wasn’t reliable enough. The chance that these processes gets restarted during a login session is possible unlike the loginwindow process. When the login window get restarted the user is logged out again as well.