do shell script passwords explaination

You’re passing the password to the do shell script, so unless sudo requires another user than the current shell user, you will be never prompted until you recompile the script. But when you’re not in the sudoer’s list, you will be prompted again, so therefore it’s wise when you send the password, you also send the username where the password is for. Because you aren’t guaranteed that the user running the script will be match the user you’re providing the password for. It depends on the user who is running the process that contains the running instance of AppleScript (user of current application).

do shell script "echo 'hello world!'" user name "<shortname>" password "<password>" with administrator privileges

Hello.

Slightly off topic, I liked the usage of exist for checking if a property has been intialized, and wanted to replicate it for global variables, since the usage of exists doesn’t work before a global has been assigned a missing value.

global tp

set tp to assert(a reference to tp, missing value)
log tp
on assert(avar, initval)
	(*

The assert handler takes advantage of the fact that a script will throw an error if you assign a value from an unasigned variable to another. (Naturally). If that error is thrown, then we set a value to the variable we want to assert that have a  value in the error clause of the try block.

Otherwise if everything is ok, (the variable we want to assert has a value does have one), we just return the value the variable already had. 

We have to  return a value though, because the reference won't work, as long as no value is assigned to the variable we want to assert has a value.

The reason for using a reference is that we do need to pass the variable by a reference, since we otherwise will get the unassigned error thrown the moment we try to pass the unassigned variable to the handler. -Which alleviates the need for a handler, but leads to lot of clutter and repeated code if you need to assert more than one variable.
*)
	try
		set dummy to contents of avar
	on error
		return initval
	end try
	return contents of avar
end assert

Good Morning here!

Hi Dj,

What a coincidence. I was just looking at the ‘do shell script’ parameters and was wondering why you would want to add the administrator name! What you say makes a lot of sense. Thanks.

Hi McUsr,

Tricky script! :cool: I need to look at that again. Thanks.

Have a good day what ever is left of it on that side of the world. :slight_smile:

Thanks a lot,
kel

ps. I’ve been trying to sum up everything while driving this morning. Think i have it.

Hello kel.

I have updated the comment in the post. It is a bit tricky. If you don’t understand the comment, then just ask. :slight_smile:

Here’s the final template script if anyone is interested:

property pw : missing value
property admin_name : "kelhome"

-- if first run then get the passwd
if (pw is missing value) then
	display dialog "Enter password for " & admin_name & ":" default answer ""
	set pw to text returned of result
end if
-- set seconds to add to current date for target date
set targ_secs to 1 * minutes
set cur_date to current date
set target_date to (cur_date + targ_secs) as «class isot» as string
-- format iso time for pmset
do shell script "date -jf '%Y-%m-%dT%H:%M:%S' '" & target_date & "' '+%m/%d/%y %H:%M:%S'"
set format_date to result
-- schedule wake from computer sleep (or display sleep)
-- on first run, user must enter admin password twice
-- needs admin password once to avoid password entry dialog after timeout
-- second password dialog enters the admin info in sudoers' file
-- can adjust timeout to never (0), using visudo (see man page)
do shell script "pmset schedule wake \"" & format_date & "\"" user name admin_name password pw with administrator privileges
-- display sleep
do shell script "pmset displaysleepnow"

Added quick summary and explanation in the comments.

Thanks a lot everybody, :smiley:
kel

Nice script kel :cool:

I agree fully with DJ :cool:

The script is very useful by itself, but the storing of password makes it even better. It should even be possible to make it re-enter the password for the case that you change it. And then, if the script is stored as run only, I guess it will be a little bit harder to figure out the password. (I think you can read out stored properties, and maybe variables too with Script Editor, even if they aren’t declared in the script, but I don’t think that works when the script is stored as run only.)

Thanks.

It’s a cobbling together from many sources including the date format from Nigel’s scripts. I was thinking about using the short version with ‘+%D %T’, but might copy and paste this format for other formats.

I’ve been wanting to clear up my password confusion for over a year, but went into the addictive video game mode for a while. :slight_smile:

Thanks again,
kel

Hi McUsr,

This is a way to use an undefined variable!

global tp

a reference to tp

:cool:
Nice one. People think that when you get the undefined variable error, that you need to define it first. Me. :smiley: I’ll put that in my bag of tricks.

The day passes so quickly.

Have a good day,
kel

I was just thinking about a question I asked before.

When you run a program, is there a way so that on the first run you run some program and on the second run, there is no if statements or anything and the second part of the program will run. I think we found a solution. I can’t remember what the code was, but I’m sure there was a solution.

I need to search for it!

You remember, huh Nigel. Maybe we could implement that in this.

Later,
kel

I’m starting to remember it. when you run the program, the first part runs. When you run the program again, the second part runs and has nothing to do with the first part. Darn, how did that go?

there are several solutions but they depend on the type of the script.

AppleScript Properties in applets/droplets are persistent, so define a property for example firstRun with the default value of true and set it to false when the applet launches the first time.

Unlike applets compiled scripts could be recompiled at runtime, in this case you need an external place to save the information, a script (object) using load/store script or a plist file using do shell script defaults

Hi Stefan,

I remember part of it now. it was a switch. Can’t remember how it was done, but I remember it switched from one program to the other automatically.

Edited: it was all in the same AppleScript.

You see after it switched, when you run it again, it immediately jumped to the second part. i.e. the first part never runs again.

The concept was very deep.

I wish I could find the post, because I’m quite sure that we found a solution.

Hello kel.

You reall don’t have to look any further than DJ Bazzie Wazzies test if a property exists. if it doesn’t, then the script needs to be initialized for the same time. My way does the same, but is more of a kluge really.

Both of those approaches works great if the script is to be distributed at macscripters, where the script turns up in your editor, and is compiled before it is used. If you distribute a script thru email, then you should really also test for the machine name, or some other means, so that you are sure that the script is initialized the first time it is run.

The switch examples you’re looking for is launching a handler for the first time and never again, then after that launch alway the other handler. That is a workflow that doesn’t fit right in your code because you want only user interaction when a value isn’t set.

But the actual switch in handlers is probably something like this:


theHandlerReference()
set theHandlerReference to handler2

on handler1()
	display dialog "handler 1"
end handler1

on handler2()
	display dialog "handler 2"
end handler2
-- we need to define the property after defining the handlers otherwise the code won't compile
property theHandlerReference : handler1

edit: Personally not my favorite because you got rid of the if-statement but still requires a setter each run. Setting (copying) an reference to a handler each run to get rid of an boolean comparison is missing the point of efficiency. Another post of mine, which has implicitly an if-then-else statement by using logic operators and and or. is maybe nicer to look at. You get something like this then:

property userPassword : missing value
property userName : missing value

set userName to do shell script "whoami"
userPassword = missing value and setUserPasword() or setPowerManagement()

on setUserPasword()
	display dialog "Enter password for " & userName & ":" default answer ""
	set userPassword to text returned of result
	return false --return false to immediately run setPowerManagement() handler
end setUserPasword

on setPowerManagement()
	-- set seconds to add to current date for target date
	set targ_secs to 1 * minutes
	set cur_date to current date
	set target_date to (cur_date + targ_secs) as «class isot» as string
	
	do shell script "date -jf '%Y-%m-%dT%H:%M:%S' '" & target_date & "' '+%m/%d/%y %H:%M:%S'"
	set format_date to result
	
	do shell script "pmset schedule wake \"" & format_date & "\"" user name userName password userPassword with administrator privileges
	-- display sleep
	do shell script "pmset displaysleepnow" --note: this command only works in 10.9 and up
	return true
end setPowerManagement

Hi,

Yes, that was the switcher. I see now how it sets every run. I’ll probably stick with the easy to understand method. Will look through everyones post again.

Thanks a lot,
kel