Weird $KMVAR_Local_Password variable not working in Shell

Hi,

I have a simple script where I ask for a device name and a password for sudo. When trying to use the password in a Shell script, the $KMVAR_Local_Password is blank (that is the name of the variable I used); while if I try displaying it with the Display action above, it shows the variable holds the proper value entered.

If instead of using that name for the input field, I use anything else (like Local_PasswordXXX), the Shell script can read it properly. But I don't want to use anything else; I want the label in the input window to say exactly "Password" :slight_smile:

I don't know what might be going on; one guess is that the Password variable is already defined/used/reserved in the Shell environment and that it's why not outputting the expected values?

Could you please share any ideas? Thanks.

PS: Side-question; if instead of Local_DeviceName I use Local_Device Name (with a space), how can I reference that variable from Shell? I've tried adding quotes (echo "$KMVAR_Local_Device Name") but it won't work. How do I handle that space there?

Nevermind:

Keyboard Maestro sets the environment variables for the script to include all your variables, using a prefix of KMVAR_ and your variable name with spaces changed in to underscores (_). For example, your Keyboard Maestro “File Name” variable will be available as the environment variable KMVAR_File_Name .

In the KM wiki for shell script action it says this about variables:

"Keyboard Maestro sets the environment variables for the script to include all your variables, using a prefix of KMVAR_ and your variable name with spaces changed in to underscores (_). For example, your Keyboard Maestro “File Name” variable will be available as the environment variable KMVAR_File_Name ."

which means your variable name Local_Password is being passed to the shell as Local Password

OH - you beat me to it!

Thanks for sharing @tiffle! Yeah, I was reading that just after posting and added to my original message.

which means your variable name Local_Password is being passed to the shell as Local Password

That documentation made sense for "Device Name" having to be referenced as "Device_Name" in Shell, but regarding why Local_Password is not visible, but Local_PasswordX is, that still doesn't answer it sadly.

It may have something to do with KM's password variables - se the wiki here manual:Variables [Keyboard Maestro Wiki]

Having read that (under the Scope section) it looks like there may be a naming issue there, but I'm not sure. Maybe @peternlewis can shed some light on this?

I thought that with:

[Passwords]

Not directly accessible via AppleScript.

that was why that variable couldn't be readable in Shell. Changed the field type to "Text" instead of "Password", now it's plain text on the input forms and still can't be read from Shell. Then again, a variable named PasswordX, of type "Password" in the input form, CAN be read in the Shell; only because it is not called exactly Password! :confused:

Password Variables (those that start or end with PW or Password are not passed to scripts.

Thanks Peter. I imagine they are allowed to be read directly by actions? (i.e. display dialog showing it)

You mentioned those that start or end with PW or Password... then why the variable PasswordAnything (starts with Password) get passed to the Shell?

Is it PasswordAnything? Or is it, as above, Local_PasswordAnything -- which neither starts nor ends with Password?

1 Like

Good point.

So Local_PasswordPrivate gets passed around because it doesn't technically start in Password but PasswordPrivate doesn't. I would have expected the Local_ scope part to be left out of considering that, as the actual name of the variable starts after the underscore.

With that reasoning, then if you define the scope of a Password named variable, it will never be protected from being passed around, while if you don't scope it, it will.

Local_ is part of the variable's name, it's only a scope because KM interprets it in that way. Put another way, the naming enables KM to set the scope for the variable, but it's not a flag, it's an interpreted portion of the variable's name.

-rob.

Starts or ends with password. So Local_password will be scoped more tightly than a global, as will Instance_password.

Yes, you can use it in any action. The editor will not display its value.

It is not.

Local My Password would be a local variable that is also a password variable.

OK then, pretty silly (i.e. duplicate the variable with another not ending in Password), but I had to solve it like this to still be able to show "Password" in the prompt and be able to use that variable in a shell script

If this is for your own consumption you can do it like this -- but there are better ways, depending what you are actually trying to achieve.

If this is a certain command, add it to your sudoers file so you can execute it passwordless.

If you want a more general solution -- while it's true that you can't access a Password variable from the shell, that doesn't mean you can't pass a password in! If it's the first, or only, command in your shell then use sudo -S:

If you want to put the password into a variable for later/multiple use, set it from stdin:

But in general, and especially if a macro is to be used by others, the above are "bad practice". Encouraging people -- even yourself -- to put a system account password into a non-system dialog is A Bad Thing. You should always stop and question what's going on if you see it happen on your machine!

You can do things more properly by using an AppleScript action to run the shell script:

image

...and I'm sure there are other ways to do what you want more securely. Anyone?

Example containing all the actions above:

Password to Shell Script Examples.kmmacros (4.9 KB)

Image

1 Like

Thanks Nige for your thoughtful reply!

I've been moving away from sudoers, as also wouldn't be a best practice and open a lot of potential misuses (even though it's for myself only!), but I'll try your idea of setting the Input Variable right there in the Shell Script action and passing it as stdin; basically handling like this:

Local_Password from Input Form (can't be read directly in shell) -> Read Local_Password as Shell Script Action input variable -> use stdin in the shell

This seems a reasonable solution for the somewhat unusual case of where you want the label for the variable to be “Password” but don't actually want it to be a Password Variable.

There's nothing wrong with using sudoers as long as it is properly managed. Limit the scope of the commands you allow so only particular users/groups can use them, and limit the commands themselves (if you need to regularly sudo-delete directory /Library/Caches/foobar, use rm -rf /Library/Caches/foobar and not plain rm -rf).

There's even an argument that it is safer to use sudoers for restricted commands that you run on a frequent basis than to insist on password entry. "They" can't shoulder-surf your password if you don't have to type it!