The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - General (http://hintsforums.macworld.com/forumdisplay.php?f=16)
-   -   Help with the Defaults command (http://hintsforums.macworld.com/showthread.php?t=35939)

MBHockey 03-02-2005 10:00 PM

Help with the Defaults command
 
1 Attachment(s)
I am trying to edit the com.apple.powermanagement.plist file via Terminal so as to change the that my display goes to sleep. I think i pretty much understand the Defaults Write basics, however, i can't find how to do it for a nested value.

I would like to use a terminal command (and eventually save it as a shell and run it via something like XKeys) so as to change the display sleep time to 1 minute.

This is what i'm trying:

defaults write com.apple.powermanagement.plist "Display Sleep Timer" 1

And i'm assuming this would work if the display sleep timer preferenceKey was in the Root folder, but i do not know how to tell the command to edit the key that is nested within the AC Power dictionary.

Thanks.

biovizier 03-02-2005 10:40 PM

I think '-dict-add' should work in this case. eg:
Code:

sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.PowerManagement  "AC Power" -dict-add "Display Sleep Timer" -int 1
With '-dict-add', if the key already exists, it will change the value - it won't duplicate the key.

MBHockey 03-02-2005 11:14 PM

Hmm, when i run
Code:

defaults write com.apple.powermanagement.plist "AC Power" -dict-add "Display Sleep Timer" -int 10
It doesn't edit the plist i want it to, it creates a new one named:

"com.apple.powermanagement.plist.plist" in ~/Library/Preferences

And when i run exactly the code you gave me, it replaces the entire file in /System/Library/SystemConfiguration with a blank .plist of the same name.

Any more ideas? (They'd be greatly appreciated!)

Thanks

MBHockey 03-02-2005 11:41 PM

I finally found a "nested" example, but it doesn't seem to work when i basically plug-in the values i need...

Code:

defaults write com.apple.finder DesktopViewOptions -dict ArrangeBy <dnam or kind or size>
From that, i tried:
Code:

defaults write com.apple.powermanagement "AC Power" -dict "Display Sleep Timer" 10
and

Code:

defaults write com.apple.powermanagement "AC Power" -dict "Display Sleep Timer" -int 10
From: http://homepage.mac.com/pixits/defaults.htm

:confused:

biovizier 03-02-2005 11:43 PM

When you don't provide the full path to the file, 'defaults' uses '~/Library/Preferences' as its base directory, so that's why a new file was created at that location in that case.

As for getting a new "blank" file with the full path, I'm guessing it only appears to be blank because of permissions. The 'defaults' command rewrites .plist files and sets permissions to 600. When a preference pane writes a .plist, they usually get '644'. In this case, since 'sudo' was used, the file's owner will be root so you may not be able to view the file without 'sudo' - pico or vi will throw up a blank 'new' file since it can't read the existing file (although the system should be able to read it no problem). So try either of:
Code:

sudo less /Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist
sudo defaults read /Library/Preferences/SystemConfiguration/com.apple.PowerManagement

I guess following Apple's default permissions, an "admin" shouldn't need sudo to use 'defaults' for files in '/Library/Preferences' but I've seen a couple of bugs reported where non-admins can get write access to admin-writable directories. Since you can indirectly run scripts as root from files in '/Library/', I've taken away group-write permissions for that folder and everything in it.

MBHockey 03-02-2005 11:57 PM

Aha, minimal success!

running this:

Code:

defaults write /Library/Preferences/SystemConfiguration/com.apple.powermanagement "AC Power" -dict "Display Sleep Timer" -int 10
It changes the value to 10, however, that is the ONLY prefenceKey there, the other 8 disappeared. :eek:

I guess this could work if i knew how to add the other 8 things into that one line of terminal code. Is that a possibility?

biovizier 03-03-2005 12:04 AM

Yes, with keys nested within a <dict>, '-dict' will replace all of the values. Using '-dict-add' will add a nested value, or modify an existing one as described above.

MBHockey 03-03-2005 12:15 AM

Sorry for the misunderstanding...all is working now, thanks!

bramley 03-03-2005 04:22 AM

Coming into this from a different direction, you can avoid playing around with the plists (which I'm not certain will work anyway) by using the 'pmset' utility.

Type 'man pmset' for more info.

MBHockey 03-03-2005 09:10 AM

I will look into that later on today, but this way is working great. I've hooked a 1 minute timer up to Fn+F1 and a 15 minute timer to Fn+F2 via XKeys, and it's working great.

MBHockey 03-03-2005 09:16 AM

Well, this is strange. It seems to have been working (it does change the time in Energy Saver), however, my Mac doesn't listen to this new value, until i go into system preferences and do it manually.

I'll look into pmset later on today.

MBHockey 03-03-2005 02:39 PM

It seems to be working a lot better with pmset, however, i run into a snag because of the 'sudo' part.

Is there a way for me to save my .term file so that it:

1) executes the command (sudo pmset -a dim 1)
2) enters the admin password
3) quits terminal when complete

Thanks for all your help

bramley 03-03-2005 04:25 PM

I'm a basic shell scripter me. Can do this from Applescript but I don't know how to get script to execute as root.

Hal Itosis 03-03-2005 08:11 PM

Quote:

Originally Posted by bramley
I'm a basic shell scripter me.
Can do this from Applescript but
I don't know how to get script to
execute as root.

Beyond me as well, but perhaps
look on this page for the post
titled "Do not setuid your scripts!"
and see if that maybe works...

-HI-

saint.duo 03-03-2005 08:25 PM

I wrote an applescript for someone that used pmset about a year ago to change the display sleep time. He wanted it to sleep after 5 minutes at night, and 20 minutes during the day.

I'll post the script once I get a reply from him.

bramley 03-04-2005 11:28 AM

Quote:

Originally Posted by MBHockey
It seems to be working a lot better with pmset, however, i run into a snag because of the 'sudo' part.

Is there a way for me to save my .term file so that it:

1) executes the command (sudo pmset -a dim 1)
2) enters the admin password
3) quits terminal when complete

Thanks for all your help

You need to use sudoers to give your user rights to use pmset without asking for a passsword. See details here: http://www.macosxhints.com/article.p...21202054815892

MBHockey 03-04-2005 03:25 PM

Thanks -- that hint works great.

However, is there a way to get Terminal to exit upon completion of the command?

i tried:

sudo pmset -a dim 15;quit
and
sudo pmset -a dim 15; quit

neither work (but i think the first type worked with the Defaults command i was using earlier), resetting the energy saver pref works, but quitting doesn't:

Code:

bing109:/ Mike$ sudo pmset -a dim 15;quit
Warning: Idle sleep timings for "Battery Power" may not behave as expected.
- Display sleep should have a lower timeout than system sleep.
-bash: quit: command not found


hayne 03-04-2005 03:55 PM

Quote:

Originally Posted by bramley
You need to use sudoers to give your user rights to use pmset without asking for a passsword. See details here: http://www.macosxhints.com/article.p...21202054815892

I strongly recommend against implementing the above "hint". It is extremely unsafe for the reasons explained in the comments to the hint - e.g. that of 'bbum'

MBHockey 03-04-2005 04:31 PM

Yeah i tried it -- it worked, but i don't think the extra two seconds it takes me to accomplish this is worth the security risk.

Hopefully this is something that Automator can accomplish come Tiger.

biovizier 03-04-2005 05:07 PM

Instead of giving carte blanche passwordless sudo access with 'user_name ALL=(ALL) NOPASSWD:ALL' in your /etc/sudoers file, you could use:
Code:

you        ALL= NOPASSWD: /usr/bin/pmset -a dim 15
For quiting, "Terminal.app", try:
Code:

osascript -e 'tell application "Terminal" to quit'

bramley 03-04-2005 06:32 PM

Quote:

Originally Posted by hayne
I strongly recommend against implementing the above "hint". It is extremely unsafe for the reasons explained in the comments to the hint - e.g. that of 'bbum'

Uhh! Fair point. When I first read one of today's hints which linked to the one above, I read about sudoers in my 'bumper book of interesting UNIX facts' and 'man sudoers' which mentioned the use of the NOPASSWD tag to permit the use of selected commands, which Biovizier seems to have pointed out. I rashly assumed the above hint discussed NOPASSWD tags, but clearly it just disables all security everything.

Quote:

Originally Posted by MBHockey
Hopefully this is something that Automator can accomplish come Tiger.

[mock rant]
Why does everybody keep saying this? I don't know but I'm prepared to bet Automator is just a more GUIfied version for the much vaunted 'recordable' scripting mechanism that came out with 10.1. It will rely on 3rd party developers (and Apple) putting in as much effort in getting their products to 'automate' as they already have with recordable scripting support - in other words, none at all.
[/mock rant]

You could avoid using sudoers or opening Terminal at all with an Applescript and 'do shell script.' Yes, you still need your password, but you can script KeyChain Access to give this out. I'm trying to write an example to show what I mean but I'll have to post it sometime over the weekend.

[EDIT Ummm - I have managed to get this to work but have noticed a problem with KeyChain Access so probably better if I keep quiet for now]

saint.duo 03-05-2005 11:51 PM

found it
 
That friend of mine replied.

Here is the applescript I made for him to put in his scripts menu and change his display sleep time. Replace $MYADMINPASS with your admin password.

Code:

do shell script "sudo pmset dim 1" password "$MYADMINPASS" with administrator privileges
Works great for him. He has a 15 minute and a 1 minute one.

Hal Itosis 06-19-2005 07:29 AM

Quote:

Originally Posted by bramley
Coming into this from a different direction, you can avoid playing around with the plists (which I'm not certain will work anyway) by using the 'pmset' utility. Type 'man pmset' for more info.

(3 months later... guess we're running Tiger now).

Reading up on pmset, I found an interesting [optional] argument
called force. In tests I ran, it seems that we can totally avoid
the whole sudo mess... because --when "force" is deployed -- pmset
doesn't write to the plist, but rather directly to some location (RAM,
VM, register, whatever) where those variables are actively used.

From the man page:
Quote:

force - tells PM to immediately activate these settings. Does not write
them to disk, and the settings may easily be overwritten. Useful in cir-
cumstances where PM's configd plugin happens not to be running.

My display sleep is normally set to 30 minutes. But with a simple script...
Code:

#!/bin/bash
/usr/bin/pmset -a force displaysleep 1
exit 0

...I can go to black in 1 minute. No sudo, nada.

FWIW,

-HI-

elmimmo 08-03-2005 05:51 PM

Quote:

Originally Posted by biovizier
Using '-dict-add' will add a nested value, or modify an existing one as described above.

I see that this is true for something at tree level 2 (being root, Level0). That is, it keeps all other dicts in level 1 and other dicts at level 2 intact, and updates/overwrites this level 2 dict with specified keys and their values.

However, what if there where more nested dicts in the level 2 dict that we are editing. I have seen that even using '-dict-add' will wipe out any dict at level 3 branching from the level 2 dict we are editing.

In other words, how do you edit the value of the key 'Date' of dictionary 'Level3A' from '2005-07-18T21:53:04Z' to '2005-08-3T23:50:04Z' in:
Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Level1</key>
        <dict>
                <key>Level2</key>
                <dict>
                        <key>Level3a</key>
                        <dict>
                                <key>Date</key>
                                <string>2005-07-18T21:53:04Z</string>
                                <key>Value</key>
                                <string>booyah</string>
                        </dict>
                        <key>Level3b</key>
                        <dict>
                                <key>Date</key>
                                <string>2005-07-19T22:00:00Z</string>
                                <key>Value</key>
                                <string>hello</string>
                        </dict>
                </dict>
        </dict>
</dict>
</plist>


biovizier 08-03-2005 10:58 PM

I don't think deeply nested values can be edited using 'defaults' alone (I would be interested if there is a way), so workarounds will vary from situation to situation...

The example in your post is fairly straightforward, since there is only one 'Level2' entry, and all of the entries are of the string "type". There are probably easier ways, but you could for example, take the ascii formatted output of the 'defaults read' command (in which key-value pairs are conveniently placed together into lines), and process it with 'sed' or something. eg.
Code:

newdate="2005-08-3T23:50:04Z"
newL1="$(defaults read the.property.list Level1 | sed "s/\(Level3a[^\"]*\"\)[^\"]*/\1${newdate}/")"
defaults write the.property.list Level1 "$newL1"

I mentioned all of the entries being of type=string, because this process will convert everything into strings - eg. <true/> becomes <string>1</string>, or <integer>17</integer> gets changed to <string>17</string>, etc. Many programmes don't seem to care, but I've run into a few that crash so watch out.

Anyway, at this point, it becomes more of a question about "how to parse text" rather than use of the 'defaults' command...

elmimmo 08-04-2005 02:56 AM

The man page for defaults seems to explain how to set the value types of new values, choosing from string, data, int, float, bool, date…

I can see that there are sideways like editing ASCII plist, but my intention was to edit a plist from a shell script, and Tiger seems to be full of binary plists. The command plutil seems to be able to convert from binary to xml, but not to ASCII.

Maybe I can use sed, too, or other command to go through an ASCII file with line breaks, but I will have to look into that, and my shell skills are limted…


All times are GMT -5. The time now is 06:22 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.