I use Terminal everyday, and I find it a good idea to log everything I you. It makes it much easier to undo your mistakes when you know what those mistakes were. Here's how I do this:
Open Terminal's preferences.
Go to Settings, then Shell. You can choose here to run a command at startup. You could create a simple log of your session using the following:
/usr/bin/script ~/Desktop/Terminal.log
This will log everything you do and append it to the log file.
I like to keep my history so instead I wrote this small script that archives previous sessions by renaming the file with a date/time string. I then set Terminal.app to run at startup the following command:
~/Desktop/logger.sh
Here's the script:
#!/bin/bash
# logger.sh
# Log everything you do in Terminal.
#* Formatted date & time string.
FORMATTED_DATE=`/bin/date "+%Y-%m-%d%H%M%S"`
#* Archive the previous file
/bin/cp -f ~/Desktop/Terminal.log{,.$FORMATTED_DATE.txt}
#* Begin a new one
/usr/bin/script ~/Desktop/Terminal.log
[kirkmc adds: This is a good idea. I don't use Terminal a lot, but I find that I sometimes need to remember a command I ran in the past which is no longer in my history.
Also, this is similar to something I do with texts I write. I do most of my writing in BBEdit, and I have a number of "scratch" files which I change every year. For example, I have one file for most of what I write, another just for Mac OS X Hints, and another for a specific client I write for. I archive these files at the end of the year, and create new ones. If I ever need to go back to these files to look for something I can do so. I don't bother to enter dates - which I could do easily enough with a TypeIt4Me shortcut - but if I'm looking for something I'll generally know what text to search for.]
Often times, for whatever reason, the Internet connection on my Mac will lock up. Only restarting the Airport or Ethernet interfaces seem to resolve the issue in a timely manner. (This is different from a router crash which requires a manual restart of the router - in my case an Airport Extreme.) I have developed some interconnected scripts that will automatically accomplish this task for me when attached to launchctl. This is important for me because I often have to access files over the internet and if the connection has locked up there is no way for me to access them without manual intervention.
The first script gets the active network interface. This is called by the second script which determines whether to run a matched script for either the Ethernet or AirPort interfaces. These third and fourth scripts restart either the Ethernet or AirPort connection respectively. These last two scripts can also be configured to send you an e-mail if this happens by altering the 'tobenotified" string to reflect your e-mail address in each of them. Be sure to maintain the single quotes. Or, if you do not wish to receive e-mail, comment these parts out.
Name the first script "active_interface.sh", and the second "check_internet_master.sh". This second script is what controls the rest. Attach it to lauchctl to do this automatically and never worry about a lost connection. The third and fourth scripts should be called "check_internet.sh" and "check_internet2.sh". Of course you can always name these whatever you want, but be sure to put the path to them in the scripts. Make sure to chmod all the files executable; and, unless the scripts are altered, they should also be run from the same folder.
In order for ifconfig to run with out intervention, the script needs to be run as root. Alternatively, you could make an exception for ifconfig in your /etc/sudoers file by adding the line (if you run as admin - else put %users):
%admin ALL= NOPASSWD: /sbin/ifconfig
I don't think this is too much of a security issue.
With this setup, I find I am nearly impervious to lost connections.
Sometimes applications have a nasty habit of claiming a lot of memory and never releasing it back to the system. Over time, this can cause affect performance. Most of the time, this can simply be fixed by quitting and restarting the offending program, but I wanted to find a more elegant solution.
After searching the Internet, I found few scripts that I could tweak to achieve what I wanted. Heres what I came up with. The first script is a python script I found at StackExchange by user drfrogsplat that gets information about system memory. The second is a bash script I wrote that runs the purge command if you have over a certain amount of inactive memory, in my case 500MB (probably overkill). Note that I think you need developer tools installed to use the purge command. There's probably an easier way to do this with vm_stat directly but I'm not good enough at awk/grep/sed to it figure out.
The bash script can be attached to a launchd plist to run automatically at certain intervals or whenever you want. I seems to work pretty well for me.
#!/usr/bin/python
import subprocess
import re
# Get process info
ps = subprocess.Popen(['ps', '-caxm', '-orss,comm'], stdout=subprocess.PIPE).communicate()[0]
vm = subprocess.Popen(['vm_stat'], stdout=subprocess.PIPE).communicate()[0]
# Iterate processes
processLines = ps.split('\n')
sep = re.compile('[\s]+')
rssTotal = 0 # kB
for row in range(1,len(processLines)):
rowText = processLines[row].strip()
rowElements = sep.split(rowText)
try:
rss = float(rowElements[0]) * 1024
except:
rss = 0 # ignore...
rssTotal += rss
# Process vm_stat
vmLines = vm.split('\n')
sep = re.compile(':[\s]+')
vmStats = {}
for row in range(1,len(vmLines)-2):
rowText = vmLines[row].strip()
rowElements = sep.split(rowText)
vmStats[(rowElements[0])] = int(rowElements[1].strip('\.')) * 4096
print 'Wired Memory:\t\t%d MB' % ( vmStats["Pages wired down"]/1024/1024 )
print 'Active Memory:\t\t%d MB' % ( vmStats["Pages active"]/1024/1024 )
print 'Inactive Memory:\t%d MB' % ( vmStats["Pages inactive"]/1024/1024 )
print 'Free Memory:\t\t%d MB' % ( vmStats["Pages free"]/1024/1024 )
print 'Real Mem Total (ps):\t%.3f MB' % ( rssTotal/1024/1024 )
==============================================================
==============================================================
#!/bin/bash
MM=`/Path/to/python/script.py | awk '/Inactive/ {print $3}'`
echo "Testing status of inactive free memory..."
if [ "$MM" -gt "500" ]; then
echo "You have too much inactive free memory." $MM"MB Releasing now..."
purge
exit 0
else
echo "Memory ammount" $MM"MB does not meet purge threshold."
exit 0
fi
[kirkmc adds: I'm guessing that this will be controversial. There seem to be dozens of apps on the Mac App Store that free up memory, and I'm not convinced that this is necessary. The only time I would see this as being essential is if that inactive memory is leading to more paging. Lately, I've been amazed at how little paging my Mac mini does; with 8 GB RAM, it rarely uses more than one swap file, and this with an uptime of several days.
I think that, in most cases, if you encounter an issue with memory, it's just as simple to use the purge command in Terminal. And, yes, I do see certain applications and processes taking up a lot of memory, notably iTunes and WebProcess. But note that the purge command doesn't free up all inactive memory anyway.
And, can someone confirm that Xcode is needed to have the purge command? Mine is in /usr/bin, and I don't think Xcode installs anything there, at least any more, now that it gets put in /Applications.]
lpadmin and lpoptions don't interact with OS X as you might think, or at least as they are documented. Here are some helpful notes and a script.
There are some good hints for adding printers via the command line with lpadmin: Managing multiple printers via the command line.
However, there is still confusion surrounding the setting of printer options from the command line, as a poster to Debian bugs pointed out back in 2006: lpoptions documentation doesn't. After doing some testing, here are the two main points to note:
If you use lpadmin and specify options with "-o", the PPD is altered and OS X will recognize the options for the printer.
However, if you setup the printer using lpadmin without any options, and later use lptoptions to set the options, they are not written to the PPD and the GUI is unaware of the printer's options.
More helpful hints about lpadmin and lpoptions:
lpoptions -p printername -l
Prints PPD options, "Default" is filtered from option name (similar to looking at the raw PPD)
It uses a colon when reporting key value pairs; replace that with an equals sign when specifying an option
The option name stops at the first slash
Example: The duplex option for HP printers will output like this "HPOption_Duplexer/Duplex Unit: *True False" When specified as a "-o" option it would be "HPOption_Duplexer=True"
lpadmin ... -o this=that
Alters the ppd that is placed in /etc/cups/ppd/ when the printer is installed
Unhelpful things: lpoptions -p printername
These are NOT the PPD options you want to set
lpoptions -o
This only writes options to: /private/etc/cups/lpoptions (run with sudo) or ~/.cups/lpoptions (run as current user), GUI apps are unaware of these options
It seems that 10.7 no longer wants to run shell scripts from the script menu. This may also happen in 10.6, but I do not have an install to test it with.
No matter what script I try, the SystemUIServer crashes. And somewhere in the crash report is this ominous message:
This might have something to do with Apple tightening privileges for spawning processes, but it can be easily fixed by enclosing the shell script in AppleScript.
do shell script "sh ~/script.sh"
[kirkmc adds: I haven't tested this; I don't run shell scripts from the script menu, so I haven't seen crashes.]
Not sure if this was available before 10.7, but hitting Control+T while running a command in the Terminal will show what process is executing, the load, the PID of the process and its user and kernel time.
I was running a script and accidentally hit Control+T instead of Command+T to create a new tab. I was surprised at what I got. Here is an example of what gets printed:
[crarko adds: I wasn't able to reproduce this, but it may be due to the briefness of the running command. Give it a try and post a comment about your results. Try it in Snow Leopard too if you can.]
There was a recent article on the Macworld main site about apps you can buy that will strip formatting from text on the clipboard, leaving you with plain text that you can paste into documents without it having the wrong font, etc.
Although some of them do this automatically, I thought it's a bit much to pay for such a simple utility that can be done in one line on the CLI.
So here's a shell script that will convert the contents of the clipboard to plain text.
The encoding option specifies MacRoman (30). I find that the default, UTF-8 doesn't always cope well with things like curly quotes.
If you have the AppleScript script menulet active, you can store the script in /Library/Scripts, and you can select it from the menu. It will run without opening the Terminal, as per this hint.
[crarko adds: This seems to work as described; I had to run the script twice before it did though.]
[crarko adds: I haven't tested this one. Note that to use MacPorts you also need to have Xcode installed to compile the ports. If you already have MacPorts set up give this hint a try and let us know how efficient the compression is for you.]
In a previous hint, I suggested to install the development version of the GIMP (which also has the new, well-known single window mode) in an Ubuntu virtual machine: which obviously wasn't an optimal solution.
Now, there is another option: install the GIMP 2.7.3 via MacPorts; here's how to do it.
First of all, if you don't have it yet, you need to install MacPorts, available from here.
It is always a good thing to do a selfupdate; in the Terminal type:
$ sudo port selfupdate
Now, we can install the GIMP's development version (currently available in version 2.7.3):
$ sudo port install gimp2-devel
There are also many, many dependencies, and thus many packages to compile form source, so you must be patient; it can take several hours (for me, on a 2010 Core 2 Duo Mac mini Server with 8 GB of RAM, it took approximately 5 hours).
Once installed (gimp2-devel will be the very last package to be compiled and installed), you can run it, again from the Terminal:
$ gimp
It is an X11 program, so this command will first launch X11 or XQuartz (in your Utilities folder), and then the GIMP.
One problem is that there are only two default themes, so, if you want a better look and feel, just take the additional themes from the current OS X version of GIMP, available from here (the Snow Leopard version works fine in Lion).
To get the additional themes ('Glossy P', 'Leopard', 'ProApp' - rather cool! - and 'Tiger') also in GIMP 2.7.3, just copy them from
Obviously, also this one is not an optimal solution, as it takes several hours to compile everything from source, but it can always be interesting as an experiment.
The best thing would of course be if eventually there were a precompiled version available, from the 'Gimp on OS X' site or elsewhere: so, let's hope that this will be the case, at least for the final GIMP 2.8 release.
[crarko adds: On the off chance that someone reading this doesn't already know, The GIMP is an image manipulation program, along the lines of Photoshop. One of the big winners of open source.
P.S. The site was hit with a ton of spam, and while I'm cleaning that up this will be the only hint published today. Hopefully things will be better tomorrow.]
Using SSH to connect to some servers can introduce long delays from the time the command is issued until the connection with the server is established. This hint describes two potential problems and offers a solution.
In connecting to a local server, my ssh command would take about 20 seconds to complete. Non-Macintosh clients would not see this delay. After searching for the web and slogging through a number of posts that suggested how to change the server to fix ssh delays, I pieced together enough information to find out how to change my client configuration to solve the problem.
The first, and largest cause of delays, was my client and the server working to authenticate me using 'GSSAPI' (Kerberos) authentication. That seemed to be a good 15-18 seconds of the delay. I fixed this problem by adding a configuration file for my user that disabled GSSAPI authentication for the host. The file I added is ~/.ssh/config and I created it to read:
Host -host-name-here-
GSSAPIAuthentication no
GSSAPIKeyExchange no
Where -host-name-here- is replaced with the name of the host so that it matches whatever you type into the ssh command. If you want to disable GSSAPIAuthentication for all hosts you can use an asterisk '*' as a wildcard host name.
That took the delay down to about a second or two. Based on another hint found in this forum, I discovered that the Mac also tries to negotiate with the server through both IPv4 and IPv6 channels. This server doesn't do IPv6 so I changed my ssh config to read:
Host -host-name-here-
GSSAPIAuthentication no
GSSAPIKeyExchange no
AddressFamily inet
This forces ssh to use only IPv4 and made my ssh connections almost instantaneous.