Files with Japanese names that show up fine when I'm in the local terminal, all turn into ???? when I ssh in from my laptop. It's because the locale of the remote sessions is ignoring the default locale and encoding of my local terminal. My local terminal defaults to "en_US.UTF-8," while the ssh sessions are something called "C," which apparently doesn't support Unicode.
One solution I've discovered is to to edit the ssh_config and sshd_config files so that the client sends the language environment variables, and the server accepts them. I've created two commands you can run in Terminal to achieve this:
On the server, you should run:
sudo sh -c 'printf "\n\n# Accept language environment variables\nAcceptEnv LANG LC_*" >> /etc/sshd_config'
and on the client, run:
sudo sh -c 'printf "\n\n# Send language environment variables\nSendEnv LANG LC_*" >> /etc/ssh_config'
These commands append lines to your config files. They tell your client and server to respectively send and receive only the environmental variables that control language. You do not have to restart the server after running this command because the new config will be applied to the next session.
If you have the problem that OS X doesn't recognize your FAT/NTFS partition because GNU parted changed the partition type to "Microsoft Reserved," this might help.
In GNU parted, it looks like 'msftres' was a flag, but this is not the case. It refers to the partition type 'Microsoft Reserved,' which can be used for NTFS and FAT. The partition type 'Basic data' can also be used for these file systems, which is then recognized by OS X.
Fortunately Linux also uses 'Basic data' for its main partitions, so the solution is to change the file system type to ext2 using GNU parted.
Many contributors have come up with ways to read man pages in a more usable format. However, using troff to produce PDFs takes time and I don't really like the output. There are also some excellent man page reading apps out there, but they require launching and browsing a list.
So I came up with a simple shell function to provide exceptionally fast lookups from the Apple Developer site's HTML man pages. That way, you get your nicely-formatted Darwin-specific man pages in a tab in your browser.
The function uses man -w to get the section number and then forms a URL which then gets launched. The web pages are organized by section, and so the URL is not straighforward. I'm new to sed, and my guess is that there are readers that can improve my regex. I've tested this with with a variety of commands, but certainly not exhaustively.
Drop this into your user's .bashrc file. You should also put it into .bash_profile if you maintain them separately -- my .bash_profile has a single line (source ~/.bashrc), so I only have to maintain one.
function wman() {
url="man -w ${1} | sed 's#.*\(${1}.\)\([[:digit:]]\).*\$#http://developer.apple.com/documentation/Darwin/Reference/ManPages/man\2/\1\2.html#'"
open `eval $url`
}
Thereafter, you can just type wman and the name of the command you want (e.g., wman rsync). If anyone knows how to automatically scroll the browser down to the horizontal rule, I'd love to know how. There are no named anchor points in the pages, so a # in the URL doesn't work.
While browsing commandlinefu.com (a very useful site, by the way), I found this gem that uses Python to quickly set up a webserver for the current directory in Terminal. First launch Terminal and cd to the directory you'd like to access via your web browser. Then just use this command to start a webserver serving just that folder (and folders within it):
python -m SimpleHTTPServer
The webserver runs on port 8000, so to access the pages in your browser, you'd use http://localhost:8000. If you'd rather run the webserver on another port, just include the port number on the python line: python -m SimpleHTTPServer 8080.
Depending on which browser you're using and the files you're browsing, you may be able to open the files in the browser, or via a helper application. Safari, unfortunately, wants to download file types it doesn't know about, which may not be all that useful.
To quit the server, press Control-C in Terminal (does anyone know a more graceful way to do this; Control-C throws a bunch of errors as it quits?).
Terminal is very useful in managing of rooms of Macs with Apple Remote Desktop. One thing I do often is change the screen resolution. To do that, I use a custom Terminal program that's based largely on Jeffrey Osterman's code posted in this Mac OS X Hints Forums thread.
It is easy to compile (you'll need Xcode to do so, however), and it supersedes the old and missing cscreen. First, here's the code:
/*
* setgetscreenres.m
*
* juanfc 2009-04-13
* Based on newscreen
* Created by Jeffrey Osterman on 10/30/07.
* Copyright 2007 Jeffrey Osterman. All rights reserved.
* PROVIDED AS IS AND WITH NO WARRANTIES WHATSOEVER
* http://forums.macosxhints.com/showthread.php?t=59575
*
* COMPILE:
* c++ setgetscreenres.m -framework ApplicationServices -o setgetscreenres
* USE:
* setgetscreenres 1440 900
*/
#include <ApplicationServices/ApplicationServices.h>
bool MyDisplaySwitchToMode (CGDirectDisplayID display, CFDictionaryRef mode);
int main (int argc, const char * argv[])
{
int h; // horizontal resolution
int v; // vertical resolution
CFDictionaryRef switchMode; // mode to switch to
CGDirectDisplayID mainDisplay; // ID of main display
CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display);
if (argc == 1) {
CGRect screenFrame = CGDisplayBounds(kCGDirectMainDisplay);
CGSize screenSize = screenFrame.size;
printf("%d %d\n", screenSize.width, screenSize.height);
return 0;
}
if (argc != 3 || !(h = atoi(argv[1])) || !(v = atoi(argv[2])) ) {
fprintf(stderr, "ERROR: Use %s horres vertres\n", argv[0]);
return -1;
}
mainDisplay = CGMainDisplayID();
switchMode = CGDisplayBestModeForParameters(mainDisplay, 32, h, v, NULL);
if (! MyDisplaySwitchToMode(mainDisplay, switchMode)) {
fprintf(stderr, "Error changing resolution to %d %d\n", h, v);
return 1;
}
return 0;
}
bool MyDisplaySwitchToMode (CGDirectDisplayID display, CFDictionaryRef mode)
{
CGDisplayConfigRef config;
if (CGBeginDisplayConfiguration(&config) == kCGErrorSuccess) {
CGConfigureDisplayMode(config, display, mode);
CGCompleteDisplayConfiguration(config, kCGConfigureForSession );
return true;
}
return false;
}
Save that as a pure text file named setgetscreenres.m, then compile it in Terminal using the command shown in the code (assuming you're in the directory where the file is saved):
c++ setgetscreenres.m -framework ApplicationServices -o setgetscreenres
Move this file somewhere on your user's $PATH, and then use it by typing setgetscreenres hor_res vert_res, where hor_res and vert_res are the desire horizontal and vertical resolution.
[robg adds: I compiled this, then tested it, and it works as described.]
If, for some reason (space in my case), you want your applications to reside somewhere other than /Applications, you will still want to have links to those relocated programs in /Applications. For Apple applications, updates are likely to fail if the applications aren't located there, and tools like AppFresh only search that location.
Creating a bunch of aliases is tedious, so here's a quick Terminal trick (that I didn't think would work, as it doesn't under Linux):
$ cd /Applications
$ ln -s /path/to/apps/* .
Change /path/to/apps to the path to your replacement Applications folder, and then run those two Terminal commands (don't overlook the very-important . at the end of the second one), and you're done.
Many Unix users may be familiar with ClusterSSH. This tool allows you to open up ssh terminal sessions to many hosts (like when administering a cluster), and then send commands to all of the connected machines simultaneously. csshX is a free, open source tool inspired by ClusterSSH, but designed to work with the OS X Terminal.app (rather than X11's xterm). Once downloaded, the csshX script can be run where it is, or copied into /usr/local/bin/ (or any other directory on your path) for convenience.
The basic command line is:
csshX hostname1 hostname2 hostname3 [...]
This will open three Terminal windows, and ssh into hostname1, hostname2, and hostname3, connecting to one host per window. A fourth (red colored) controller Terminal window will also be opened (this screenshot demonstrates how things look). Any commands typed into the controller window will be sent to all three hosts. You can also send commands directly to only one of the host terminals by selecting its window directly.
For advanced use, menus can be brought up by pressing Control-A. These menus provide you with options such as disabling/enabling input to individual windows, minimizing all the windows, retiling the windows, etc.
[robg adds: This worked as described in testing with my, um, two-machine cluster, and I can see how this would be very useful for those working with a larger number of machines.]
"A little knowledge is a dangerous thing" as they say. A long story for a problem people may rarely if ever encounter, but here goes:
I love TextWrangler for editing all kinds of text files. I set it to save in UTF-8 (with the initial byte order mark, or BOM) set by default. I discovered that the BOM makes Safari read HTML as Unicode automatically, without the need for a charset declaration, or messy entity codes for special characters. So now I can just type HTML freely in any languages and scripts I want.
Now over to Terminal: On my old Mac, I had a few default aliases set up for tcsh. I learned that now in Leopard the default shell is bash, which I am happy to note supports Unicode in pathnames seamlessly, but which uses a very different structure for keeping default aliases. I found my old ~/Library » init » tcsh » aliases.mine file and did my research: I copied the file, saved it as ~/.bash_alias, and created ~/.bash_profile to source it.
But nothing would work. I got the strangest errors, like -bash: source: command not found. Say what?! The command is right there in /usr/bin/ where it belongs! I dug for answers on the net for hours, and kept trying things. Eventually I noticed that when I executed ~/.bash_alias myself on the command line, all but the first of my aliases loaded. When I changed the file to start with a blank line, all aliases loaded, with one error about an empty command. Ahha! So the problem turned out to be the file format: the BOM made the first word of the first line into nonsense. So I resaved both of my dot-files in "UTF-8, no BOM" mode, and all is well.
As a Linux SysAdmin, of course my favorite desktop is OS X! On my MacBook Pro, I run CentOS using VMware. In my work, every day I use a fantastic technique called SSH Bouncing, both from within the VMware Linux environment and from Terminal on the Mac itself.
Explained in simple terms, assume you're on a computer, A, and you want to ssh into a computer (say, C) that is isolated from the world on a private network. If a computer B exists (and you already have an account on it) that has two network interfaces, one facing the internet (or at least the network you're on) and the other facing the private network, SSH Bouncing let's you ssh directly from computer A to computer C in one jump, with no added software or weakening of your security setup, as it requires the already-existing account on computer B.
This greatly simplifies file transfer, since you don't have to do the two step "SSH Hopping" of A » B, B » C. And popping a graphical X-Window off of C » A isn't possible at all without this technique. See this article for all the technical details on setting this up. It's very straightforward, and you'll need to understand it first for this hint to be useful.
Anyway, the point of this hint is that I used this all the time under Tiger, and when I upgraded my home and work Macs to Leopard, this broke. Specifically Mac » Mac » (destination) bouncing broke. I kept getting "Connection closed by remote host" errors.
With today's increased Flash storage sizes, there may not be many times when you need to split files. However, when you do need to do so, I find that tar is a good tool (this hint is also good if you want to split an archive before burning to DVDs).
The following use of bash's brace expansion makes creating multi-volume tar files easy. To create a multi-file archive of a given length, use this:
tar --tape-length=102400 -cMv --file=tar_archive.{tar,tar-{2..100}} [files to tar]
To extract from the archive:
tar -xMv --file=tar_archive.{tar,tar-{2..100}} [files to extract]
To create DVD-sized volumes, use --tape-length=4588544. In the above examples, replace [files to tar] and [files to extract] with the location(s) of the file(s) you wish to segment.