Applescript for macports repository maintenance - applescript

Cannot create a useful script for scheduling the macports update and upgrade weekly e.g..
I tried a tiny script here:
on run {input, parameters}
do shell script "sudo /opt/local/bin/port selfupdate && sudo /opt/local/bin/port upgrade outdated && sudo /opt/local/bin/port clean --all installed" user name "<username>" password "<password>" with administrator privileges
return input
end run
And put this into Automator
Then as it running, the window will be frozen and if anything returns during the run, it shows as an exception message.
Can you write a useful script to get things done?
Thanks for help!

I think you are better off looking into the cron utility, that nowadays must be explicitly enabled. For all what I know, you can also get hold of a utility named Cronnix, to set it up. Your other alternative is to use Launchctl, here there is a friendly user interface named Lingon, that you can buy from the appstore.
There will always be an error log from updating MacPorts, that you should really read. The other thing is that when some packages gets deprecated, or some conflict occurs, then the update command really will require you to interact, by moving stuff aside, so the approach of using something to update Macports isn't as favourable as it may seem.
How about creating a recurring calendar event reminding you to do it? :)
If you are really tenacious about getting this to work, then you'll have to use the do shell script with administrator privileges, and if you don't like the dialog with password, and username, then you can hardcode those into your automator action. You'll then have to let go of sudo, since the ´with administrator privileges` does that for you.
do shell script "your shell script without sudo" user name "hardcodedusername" password "hardcodedpassword" with administrator privileges

Related

Restarting the video assistant with a simple command

Original problem: on my MacBook Pro, the video camera keeps freezing. Found the solution is to type
sudo killall VDCAssistant
in a terminal, and provide my password (I have admin privileges).
Now I would like to make this a single command (that doesn't need a password). I found that it is possible to use visudo to edit a file that tells sudo what commands might be run without requiring a password. Obviously it would be too dangerous to make killall itself "password free", so I was hoping I could wrap the specific command inside another script; make that script "password free"; and get on with my life. So here is what I did:
Create a file called video, which contains
!#/bin/bash
sudo killall VDCAssistant
Put it in /usr/local/bin, give permissions chmod 700 video, and rehash. When I type video, I get prompted for my password. So far so good.
Next, I ran visudo and added the lines
User_Alias USERS = myusername
CMND_Alias CMDS = /usr/local/bin/video
USERS ALL = (ALL) NOPASSWD: CMDS
But that doesn't have the desired effect. I am still prompted for the password. If I make root the owner of the script, it doesn't change things. If I leave out the sudo part of the command, it tells me "No matching processes belonging to you were found".
Does anyone have a trick that I missed - how do I achieve my goal (using a single-word command to perform the killall for a process I do not own, without having to type my password)?
I have read the answers to how to run script as another user without password but could not find anything that applied here; I also read the answers to sudo with password in one command line - that is where the inspiration to use visudo came from - but again it didn't give me the answer I was looking for. Obviously I can't save my password in plain text, and I don't want to remove the "normal" protections from killall.
Is there a way to do this?
If you have an actual binary executable, you can set the setuid bit on it using chmod 4755, and then the binary will always execute as whichever user owns it (most useful if it is root, obviously). However, this doesn't work on shell scripts, for security reasons. I'm not 100% sure that this is the case, but it is possible that visudo may also be ignoring shell scripts for the same reasons.
If you've got Xcode installed, though, you can build an actual binary program to run the killall command, and then you can set the setuid bit on it. This Swift program should do the trick:
import Foundation
guard setuid(0) == 0 else {
print("Couldn't set UID 0: error \(errno)")
exit(-1)
}
let killall = Process()
killall.launchPath = "/usr/bin/killall"
killall.arguments = ["VDCAssistant"]
killall.launch()
killall.waitUntilExit()
Save the above in a text file called video.swift. Run the following command:
swiftc video.swift -framework Foundation
This will create a file called video in that directory. Move the file to /usr/local/bin, change the owner to root and setuid that sucker:
mv video /usr/local/bin
sudo chown root:wheel /usr/local/bin/video
sudo chmod 4755 /usr/local/bin/video
Now it should work.
If you want to get fancier, it would probably also be possible to rig up a plist in /Library/LaunchDaemons and get launchd to automatically kill the process every so often.
I'm a total bash noob but try checking this answer, the problem here might be with your sudoers file. I tried replicating your problem and encountered the same behaviour, with this answer I was able to make it work. I can't say anything about safety of this solution. To sum up:
I've created a file called video while logged in as root with following contents:
#!/bin/bash
sudo killall VDCAssistant
set it's permissions chmod 700 video and rehashed
using visudo I've added a following line mysuername ALL=NOPASSWD:ALL below the line %sudo ALL=(ALL:ALL) ALL since myusername is a member of group sudo
sudo video runs the script and kills the process
by adding alias VIDEO 'sudo video' to your .cshrc file, you can make this a true "one word command"
The answer by Charles Srstka solved my immediate problem; subsequent clarifications by #mspaint showed that the script-based answer could in fact also be made to work. I then discovered a nice additional touch that I wanted to share for anyone that runs into this problem. This is "how do you make the whole process seamless".
1) "Hide" the killall command in a script:
Create a text file with the following lines:
#!/bin/bash
sudo killall VDCAssistant
and save it to /usr/local/bin/restartVideo.sh
Change the permissions: chmod 700 restartVideo.sh so only you can run it.
2) make the restartVideo.sh script password-free for use with sudo
Next we need to edit the sudoers file so there is no need to prompt for the password when running the above script. The editing is done by sudo visudo - this edits a copy of the file in vim, and checks it for errors before overwriting the original. Add the following lines to the file:
# my user can run the restartVideo.sh command with sudo without password:
User_Alias ME = myUserName
Cmnd_Alias VIDEO = /usr/local/bin/restartVideo.sh
ME ALL = (ALL) NOPASSWD: VIDEO
This last line actually means "user 'ME' (defined with the User_Alias command), from 'ALL' terminals, and executing as any member of '(ALL)', can without password (NOPASSWD:) execute all commands defined by VIDEO. Save the file - make sure there are no errors / warnings! N.B.: in my original question it appears I had used CMND_Alias instead of Cmnd_Alias; that must have generated a warning that I overlooked ... and it may be the reason my original approach wasn't working (???).
3) Create a Service to invoke the script
For this I turned to the Mac Automator application - in particular, I created a new Service.
Search for the actions that have "run" in their title, and pick "Run shell script":
Using the default shell, run the command sudo /usr/local/bin/restartVideo.sh, taking no inputs. Make the command available to any application.
Finally - save the script as "Restart video".
And by miracle, you get the following menu item (showing it here for Skype):
Now you can just select that menu item, and your camera comes back to life.

interactive shell script for execution of sudo commands

I installed gcc 5.2 with gmp, mpfr and mpc, plus the isl and cloog optimizations, works perfectly. All prefixes are in /usr/local so that I have to sudomy make install's. I had to redo the same install on the computer of a friend, and now, I have to do it on another computer of mine... It's enough, so that I wrote a script. (And broke my "script whatever you have to do twice" rule.) My problem is that at some places of the script I have sudo make install commands, and that I don't want to run my script as admin.
How could I modify my script so that the following happens : before each sudo make install command one is asked to elevate permissions, and if one accepts, one is asked the root password, and then, sudo make install is executed, and after, the next commands are executed with "normal" permissions, until the next sudo make install, etc... ?
(I tagged make but the question is of course independant of it.)
sudo doesn't ask you for the root password, but your own; and it only does this when you haven't sudoed recently enough.
So just put sudo : at the top of the script: then it will ask for the password right away, and after it has been supplied, all the other sudo commands will execute without asking anything.

/bin/dash cannot find hostname

I have newly installed a remastered ubuntu 12.10. after installation I ran a script to make a standard user and do some other works. now when I log into the new standard user and open terminal, it only shows a $ mark and doesnt show username#hostname$.
it can return whoami but doesnt return anything for echo $HOSTNAME
the interesting thing is when I run bash, everything is ok, but when I run dash(which is default in ubuntu) I see the problem.
I've tried dpkg-reconfigure dash but nothing changed.
can anyone guess what is happened to my system!
thank you in advance.
I suggest to use bash instead of dash since the former is far better for interactive use.
The shell for the new user is probably set to /bin/dash, you just have to create the new user specifing the shell you want using the --shell option for the adduser command.
To change the shell for an alredy created user you can use the command chsh.

How to pass a password in bash script?

I need to execute a command which is needed to run as root.
I read some post about using hard-coded passwords in scripts could be insecure, but actually I don't care because I'm providing root password to users anyway. It's an stripped system and there's only 2 users: client and root, so avoid warning me about security issues, Go ahead and give a quick and dirty solution.
For this bash script I need to
get as superuser using su,
then "my command",
and then logout.
I don't want the terminal prompt to type the password myself, instead read the password that I'm providing somewhere in script and run the command. It's a priority to not prompt any input by user.
Alternatively, maybe I could install sudo, but is there any chance to run a command without any prompt of password (editing sudoers or something)?
What about of using expect?
Update: I forgot to say that is also a portable SO, used for USB sticks (maybe later for CDLive too), as you know, in some distros of this kind is provided a root password if users needed. The command mentioned before is a package extensions for some application install, and only root have privilegies to execute such command (I have to say it's not a apt-get install or rpm command, so don't worry about this).
If you want a command to be runnable with no password, set that specific command as runnable with no password in your /etc/sudoers file (limiting the arguments to only the specific ones you wish to allow, if your use case allows that limitation).
This is as simple as setting the NOPASSWD: flag for the relevant sudoers entry.
If you really, really don't care about security, it could be as simple as this:
%admin ALL=(ALL) NOPASSWD: ALL
(after putting sudo-capable users in the admin UNIX group)
...or, if you did care, you could do something specific:
someuser ALL = NOPASSWD: /usr/local/sbin/my_admin_command
Note that if these commands will be run with no user present, they also may not have a TTY assigned; in such a case, you must be sure that your sudoers file doesn't contain the (oft-present-by-default) line:
Defaults requiretty
...or that the effect of this default is being specifically discarded by the line granting permissions.

Is there any graphical "sudo" for Mac OS X?

I'm designing a little software in Java. I don't know the term/definition to what I'm doing, but I'm prompting commands from Java to the terminal. Something like this:
Process process = Runtime.getRuntime().exec("command");
I've done this before in Linux, and I used gksudo for commands that required the root password.
Is there any gksudo in OS X? Any graphical popup asking for root password?
You can more ore less manage to write your own with an AppleScript shell script:
#!/bin/sh
osascript -e "do shell script \"$*\" with administrator privileges"
cocoasudo looks aesthetically more pleasing, but this is already deployed.
This also looks promising: cocoasudo
It uses the OSX native Authorization Services API:
For Mac OS X Cocoa-based apps, there is analagous ability to sudo provided via the Authorization Services API. Use of the API allows you to prompt the user for their username and password requesting the ability to escalate privileges.
…
For that case, I’ve written a small utility that I’ve dubbed cocoasudo. Use cocoasudo in much the same way you’d use sudo. However, instead of users being prompted for their password in a Terminal window, they’ll get a dialog prompt via the Authorization Services API.
I found the cocoasudo doesn't work if you are running a shell script that calls other commands. You would have to use cocoasudo in all sub-commands also which would pop up a prompt for each call.
The osascript solution seems to work better, but I needed to tweak it to work with commands involving paths containing spaces.
#!/bin/sh
export bar=""
for i in "$#"; do export bar="$bar '${i}'";done
osascript -e "do shell script \"$bar\" with administrator privileges"
make the follows, in this example I go create a folder /var/lock and set your permissions to 777:
String[] command = {
"osascript",
"-e",
"do shell script \"mkdir -p /var/lock && chmod 777 /var/lock\" with administrator privileges" };
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec(command);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null)
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
on linux maybe you can make this with gksudo but I not test it, after I go testing and post here the results.
gksudo is the GTK+ version of sudo.
You can use this clone for it especially for OS X.
Following ZJR's answer, I've made this into automator, so you can use it as a Service or whatever:
on run {input, parameters}
do shell script "sudo open \"" & (POSIX path of input as string) & "\"" with administrator privileges
return input
end run
Or, maybe you just think his answer is outdated and still want an AppleScript, just write this single line in Script Editor:
do shell script "[[your command]]" with administrator privileges
Which you can then make into an app and use it as a Service or whatever.
One should use the native OS X authorization services instead of looking at sudo and/or a graphical interface to it.
Ref:
Introduction to Authorization Services Programming Guide (apple)
Authorization Services Tasks (apple)
[I know it's a late answer ...]
There seems to be a lot of wrong information in these answers. To save other people some time, I post my own findings:
First of all, like the poster of the question, I also have the situation that I need to elevate permissions from within a Java application.
I have split this up into two scripts. The first script is executed from Java with some command line parameter. The second script performs all steps that need root privileges. The idea is of course to use cocoasudo in the first script to perform the second script with root privileges.
I have confirmed via extensive logging into separate files that the scripts indeed do what I intended. And they work fine when launched manually (with normal user privileges of course) from the command line.
When launched from the Java app, I do get the cocoasudo prompt, but nothing happens. Not even the first logging output from the second script appears.
When I change the first script to use osascript, again with confirmation that everything is correct as far as the script goes, I don't even get a prompt when it runs from within Java.
This is all on OS X Mountain Lion. As if Apple build in some safe guards that prevent scripts being executed with root privileges from within Java.
Since cocoasudo itself actually runs, I am inclined to think the solution is to code something similar to cocoasudo, but performing all the rest of the required actions using Cocoa API calls. This can then be code-signed as well.
If you are using a terminal, then just use "sudo" instead, which will prompt for the user's password in the terminal itself (as opposed to gksudo which I believe uses a graphical popup). Sudo works on both Linux and OS X.

Resources