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.
Related
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
Can I execute a shell command that requires input in ipython and/or an ipython notebook?
When I execute such a command, I see it's prompt, but no apparent way to provide it with input from my keyboard.
An example could be an rsync command to a remote server (thus requiring a password). There are no doubt dangers security-wise here - these are somewhat reduced in my case as I'm running on localhost.
Reposting as an answer, with a bit more detail:
No, it's a long standing issue that's really difficult to resolve: github.com/ipython/ipython/issues/514
The issue is roughly that our architecture can't tell when a process is waiting for input, so it doesn't know to prompt the user for input.
You may be able to use pexpect and raw_input to simulate this for specific programs. I.e. if you say what the prompt looks like, it spots that in the output, and asks the user for input to send back to the process. E.g. for Python:
import pexpect
p = pexpect.spawn('python')
while True:
try:
p.expect('\n>>> ')
print(p.before)
p.sendline(raw_input('>>> '))
except pexpect.EOF:
break
I've just given this a brief test - it works, but it's fairly rough. The concept could be improved.
Sadly, no.
I couldn't find documentation on this, so I went source-diving. The ipython code that actually performs that transformation is https://github.com/ipython/ipython/blob/master/IPython/core/inputtransformer.py#L208 , specifically:
def _tr_system(line_info):
"Translate lines escaped with: !"
cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
which, in other words, invokes the underlying shell with everything following the !.
ipython is probably not what you want -- check out this answer for a Python alternate to include in scripts.
Was just looking for this and my wee face dropped when I saw it was a bit of an issue. Thought I would just post my solution in case it is usefull to anyone else.
Basically I was looking for a way to send sudo commands through the notebook, probably not very wise but I needed it for what I was doing. And i couldn't get a prompt for the password. So decided to use a x-terminal and sending the command through to the terminal. You don't get any feed back but may be due to not hooking to the IO on the way back. Here is what i used in the notebook:
In [1] !xterm -e sudo mount -o loop system.img /system/
I'm using linux but i would expect !cmd for windows might do the trick too
Many programs that require a password provide a variety of ways to prompt the user for it so that jupyter doesn't have to do it for you. The sudo command has a -A option and the SUDO_ASKPASS environmental variable. I've used it like this to use sudo to get permissions for the /var/log/btmp.1 file:
In [1]: !SUDO_ASKPASS=/usr/bin/ssh-askpass sudo -A lastb -a -f /var/log/btmp.1 | head
Similarly, for your case, ssh has an SSH_ASKPASS environmental variable.
Note that for headless operation of ssh/rsync, you can avoid authentication prompts from a notebook entirely by directly setting up an ssh agent (if it isn't running already) and referring to it with your SSH_AUTH_SOCK variable, like ssh-add does.
Or you can use a different program via SSH_ASKPASS which handles authentication in a custom way. See questions like How to automate SSH login with password? - Server Fault for more details, but be careful to not compromise your security especially when trying to automate connections from one server to another.
After some search about it I created a ~/.hushlogin file and it worked, but only for new windows. Is there a way to make it work for new tabs too?
On Mavericks, creating the empty file ~/.hushlogin removes the line “Last login”, for new windows and new tabs.
On my Mac it works.
Solution
This is running OS X 10.8.3. I haven't tested it on other versions, but so long as Terminal has the above option, then it should work.
In Terminal.app, go to Preferences->Settings and select the profile you're using. Go to the 'Shell' tab and under the 'Startup' heading, check 'Run command:' and enter into the box:
login -fpql your-username /bin/bash
Substitute your-username with your actual Unix username. If you use a shell other than the default bash shell, replace /bin/bash with the full path to that shell (yes, even if you've already set it in Preferences->Startup.)
Make sure 'Run inside shell' is unchecked.
If you have the "Prompt before closing: Only if there are processes other than login shell and:" option selected, add "login" and "bash" to the list of processes it will not prompt for.
Make sure you have a ~/.bashrc file, since this will be the file bash uses on startup from now on rather than ~/.bash_profile. I just have one file reference the other using this method. You also need to be sure it sources /etc/profile.
Explanation
We want to run login with the -q option to tell it to supress the "Last login" message, even in the absence of a .hushlogin file. (As noted above, login will only look in cwd for that file, not your home directory, so you'd need a .hushlogin file in every directory you'd open a shell to, for that method to work.)
The problem is Terminal runs something like login -pfl your-username /bin/bash -c exec -la bash /usr/local/bin/bash when you create a new shell (I'm using homebrew's version of bash, hence the weird bash path at the end,) which lacks the -q flag.
Unfortunately, there's no way to directly change the arguments Terminal uses, so we just trampoline a new login session with login -pfql from Terminal's default login -pfl session. Inelegant, but it works.
We need to have the -q option and the path to bash to keep the "New windows/tabs open with: Same Working Directory" option working. If you don't care about that option, you can remove that flag and argument, and probably avoid the .bashrc stuff above.
you could just add a clear to your .bash_profile
Adding ~/.hushlogin is fine unless you want to open a new tab in the same folder, or open Terminal from Finder on the exact folder, in that case it won't work.
Changing a running command to another login is something I would like to avoid because of the strange unnecessary scheme login -> login -> zsh. You can see it in Activity Monitor, but also it will show up when you are quitting interactive programs (like, python repl) in the message that python, login and zsh are running.
Putting clear in ~/.zshrc is not ideal since on mac it just prints a lot of newlines (and if you scroll back, you'll see them).
The best way that I found up to this point is adding printf '\33c\e[3J' to ~/.zshrc (or in Terminal/Preferences/Profiles/Shell/Startup/Run command with Run inside shell checked). I chose beginning of ~/.zshrc file since startup command is running after it and if the ~/.zshrc file is heavy you can briefly see Last Login message before printf is executed.
This might be OS version dependent. On Terminal 2.3 (on 10.8), touching the file ~/.hushlogin suppresses the 'last login' message for new tabs as well as new windows. That is, it Works For Me.
Just in case it helps to work out what's going on (and in case you don't know), note that the 'last login' message is in principle coming from login(1), and not the shell. Or, more precisely, if a shell is invoked in a particular way (including starting it with the -l option), then bash will "act as if it had been invoked as a login shell" (zsh may have a similar feature, though I can't find it right now). Now, it could be that when Terminanl opens up a new tab in your OS X version, the shell is effectively simulating opening a login shell, and maybe getting this detail wrong. But if you have the 10.8 version of bash/zsh (namely 3.2.48 / 4.3.11), then I don't know what might be amiss.
A simple solution without changing anything related to login would be just to add the clear command in the end of your ~/.bashrc or ~/.zshrc file. It will clear the terminal in initialization from any initialization prints. It works for me very well.
On my MacOS Big Sur 11.1 it works.
I want to create my own personal logfile that logs not only when I log in and out, but also when I lock/unlock my screen. Kindof like /var/log/wtmp on steroids.
To do this, I decided to run a script when I log into Ubuntu that runs in the background until I quit. My plan to do this is to add the script to .bashrc, using ./startlogging.sh & and in the script I will use trap to catch signals. That's great, except .bashrc gets run every time I open a new terminal, which is not what I want for the logger.
Is there a way to tell in Bash that the current login is a gnome login? Alternatively, is there some sort of .gnomerc I can use to run my script?
Edit: Here is my script:
Edit 2: Removed the script, since it's not related to the question. I will repost my other question, rather than repurpose this one.
Are you looking for a way to detect what type of terminal it is?
Try:
echo $TERM
From Wikipedia:
TERM (Unix-like) - specifies the type of computer terminal or terminal
emulator being used (e.g., vt100 or dumb).
See also: List of Terminal Emulators
for bash use : ~/.bash_logout
that will get executed when you logout, which sounds like what you are trying to do.
Well, for just bash, what you want are .bash_login/.bash_logout in your home directory (rather than .bashrc) These are run whenever a LOGIN shell starts/finishes, which happens any time you log in to a shell (on a tty or console, or via ssh or other network login). These are NOT run for bash processes created to run in terminal windows that you create (as those are not login shells) so won't get run any time you open a new terminal.
The problem is that if you log in with some mechanism that does not involve a terminal (such as gdm running on the console to start a gnome or kde or unity session), then there's no login shell so .bash_login/logout never get run. For that case, the easiest is probably to put something in your .xsessionrc, which will get run every time you start an X session (which happens for any of those GUI environments, regardless of which one you run). Unfortunately, there's no standard script that runs when an X session finishes.
I have written a ruby daemon and I would like for it to run when I log in. It is normally run by going to the command line and calling ruby my_ruby_script.rb. How can I start my daemon on login? (Running 10.6 Snow Leopard).
There's an option to add applications etc that need to start at login, you could try writing a shell script or an apple script thing that launches terminal and runs ruby my_ruby_script.rb, or possibly even just add my_ruby_script.rb to this list after adding a #!/bin/env ruby line to the top of that file. http://support.apple.com/kb/HT2602?viewlocale=en_US gives precise instructions as to how to add an application to be started at login.
If you need to use AppleScript to actually start a terminal application (I believe this is not the case, but I am not in front of my mac now and hence can't test), just create an applescript file with something like
do shell script "ruby <path>/my_ruby_script.rb"
Hope this helps
As Panda said, add:
#!/bin/env ruby
to the begining of the file, and then you could add a reference to your file inside ~/.bashrc or ~/.profile or even /etc/profile , depending on your needs.
Check this out: https://stackoverflow.com/questions/3484429/profile-and-bashrc-doesnt-work-on-my-mac/3484472#3484472