Posts tagged with “”

Install memcached on OSX via MacPorts

Evidently I’ve become too accustomed to MacPorts installs being just a little too easy to get working. With virtually every install I’ve done, it’s as simple as typing port install port-name (plus variants as desired). Today it wasn’t and took me far longer than it should have to track down the problem.

Having exactly zero experience with memcached, I set out to get it installed for use as a lightning quick quasi-message repository. I was a little surprised at how few instructions I found for installing the necessary components on OS X via MacPorts, but I managed to cobble together what I needed from various Linux instructions and configuration bits. I will now share the fruits of my labor with you:

 # Install the executable
 $ sudo port install memcached

# Install the bindings for PHP5 $ sudo port install php5-memcached # Verify that the executable exists in your path $ which memcached /opt/local/bin/memcached # Configure memcached to execute on startup, if desired sudo launchctl load -w /Library/LaunchDaemons/org.macports.memcached.plist # Start memcached for the current session memcached -d -m 24 -p 11211

That’s the “easy” part that I managed to get through pretty quickly. Unfortunately, it didn’t work. I wrote a simple, stupid PHP script to test and got a messaged that Class ‘Memcache’ not found. It seems that MacPorts installs all of the necessary files and even creates an Ubuntu-like, separate ini file that is included by php.ini to load the memcached extension. That file, appropriately named memcached.ini, loads the memcached extension:

extension=memcached.so

This is exactly the way I’d seen it written in each of the tutorials I’d found online, so I spent some time investigating other possibilities before I came back to it.

The problem, as it turns out, is that MacPorts doesn’t install the shared object file in its extensions/ directory. Instead, it stores it in a cryptically named subdirectory.

To get memcached fully operational I suppose you could move/copy the shared object to /opt/local/lib/php/extensions/, but I chose to edit the memcached.ini file to include the full path to the shared object:

extension=/opt/local/lib/php/extensions/no-debug-non-zts-20060613/memcached.so

I should add that I did try creating a symlink, but that didn’t work for me. Rather than spend any time figuring out whether it was a me problem, I decided to take the path of least resistance and just identify the fully qualified file path.

Restart Apache and your simple, stupid test script should work without error. For whatever it’s worth, here’s my simple, stupid script:

$memcached = new Memcached();
 $memcached->addServer( ‘localhost’, 11211 );

echo “

Memcached version:

“; new PHPDump( $memcached->getVersion() ); exit;

I’m using the php52 package (5.2.13), but I didn’t see anything to indicate that this wouldn’t work with 5.3 as well.

MacPorts, MySQL 5 and the Launch Daemons

Update, 7/29/2009: In response to my question about this on StackOverflow, Mike Richards offered an infinitely better solution. Apparently MacPorts is effectively deprecating the mysql5 +server path in favor of a new mysql-server package. I can’t confirm this personally, but it sounds reasonable enough.

That sounds a little bit like a Harry Potter title, but the content isn’t nearly as entertaining. For the past year or two, I’ve been using a MySQL installed via MacPorts, the (pseudo-) apt repository for Mac ports (get it?) of Unix applications and utilities. MacPorts has been fantastic and I haven’t regretted the decision to move away from either OS X’s native MySQL install or from MAMP, an all-in-one solution that I had used previously. The last few times I’ve installed MySQL, though, I’ve noticed that I haven’t been able to get MySQL to start automatically when I login.

Following Chad Kieffer’s excellent tutorial for installing & configuring a MacPorts MySQL install, I would get myself to the point where I execute launchctl to load the plist file that will start MySQL automatically:

$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

Unlike Chad, I want MySQL to start automatically. Admittedly, my work-life balance sucks; I’m more than likely doing something work-related if I’m sitting behind the keyboard. Given that, the server might as well be ready to respond, right? Except that the plist I’m trying to load…isn’t there to be loaded.

The first time that I did the install, the plist was there and loaded as expected, but the last 2 or 3 times that has not been the case. I don’t know what changed with the MacPorts bundle, but that plist simply isn’t there. Fortunately, I still have my old install around, so I faked it.

If anyone else is having the same issue, here’s how you too can fake it:

  1. Create a directory for the launch scripts.
    $ mkdir -p /opt/local/etc/LaunchDaemons/org.macports.mysql5
  2. Download the files that no longer get installed, mysql5.wrapper and org.macports.mysql5.plist. I’m making mine available since I don’t know where else to get them. Save both files to the directory you just created.
  3. Set the proper ownership and permissions.
    $ sudo chown root:wheel /opt/local/etc/LaunchDaemons/org.macports.mysql5/*
    $ sudo chmod 755 /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper
    $ sudo chmod 644 /opt/local/etc/LaunchDaemons/org.macports.mysql5/org.macports.mysql5.plist
  4. Create a soft link to the newly downloaded plist file in /Library/LaunchDaemons.
    $ cd /Library/LaunchDaemons
    $ ln -s /opt/local/etc/LaunchDaemons/org.macports.mysql5/org.macports.mysql5.plist org.macports.mysql5.plist
  5. Load the plist file, as indicated in Chad’s instructions and duplicated above. For the sake of keeping it all in one place:
    $ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
  6. Reboot.
  7. Verify that MySQL has started.
    $ sudo ps -ef | grep mysql

You should see output that looks something like this:

    0    65     1   0   0:00.00 ??         0:00.00 /opt/local/bin/daemondo --label=mysql5 --start-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper start ; --stop-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper stop ; --restart-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper restart ; --pid=none
    0    85     1   0   0:00.01 ??         0:00.01 /bin/sh /opt/local/lib/mysql5/bin/mysqld_safe --datadir=/opt/local/var/db/mysql5 --pid-file=/opt/local/var/db/mysql5/rob17.local.pid
   74   111    85   0   0:07.48 ??         0:19.75 /opt/local/libexec/mysqld --basedir=/opt/local --datadir=/opt/local/var/db/mysql5 --user=mysql --pid-file=/opt/local/var/db/mysql5/rob17.local.pid --socket=/tmp/mysql.sock
  501  3370  3145   0   0:00.00 ttys003    0:00.00 grep mysql

If you do, then you’re golden. If you don’t, then you probably made a mistake. If the mistake is mine, please let me know in the comments and I’ll make the appropriate adjustments.

Tab Completion for CDPATH on Mac

Though I’ve written several shell-related posts, I’m not a shell geek. Let’s get that out of the way right now. The shell is a tool for me and nothing more. I had used tcsh for years and years and years for no other reason than someone told me it was better than bash when I first started doing any “real” Unix work. I recently moved to bash because, frankly, I was tired of having to custom-configure every system I login to on a regular basis. Bash is the default shell for most Unix flavors and since the shell is only a tool, I saw no reason to continue spending time on customizations.

The other day when @patrick_mc dropped a link to a bash mastery article in a tweet, I saw the opportunity to learn something. Though it was hardly a masterful type article, I did learn about one thing that I didn’t know about before: CDPATH.

The details of CDPATH are outside of the scope of this post, but the gist is that it works the way that the PATH works. Type a directory and if it’s in your CDPATH, the OS will find it and change to that directory by name alone – even if the directory name isn’t in your current working directory. For example, if I’m in my home directory, I can type www and be delivered directly to /Users/me/Development/www as long as /Users/me/Development is in my CDPATH.

When I first read the article, I was at work and on my Ubuntu machine so I tried it there first by adding the following line to my /home/me/.bash_profile:

export CDPATH=.:~:~/Development

After sourcing ($ source .profile) my updated profile, I was able to jump to directories exactly as advertised. Moreover, tab completion worked brilliantly so, from my home directory, I could type cd w[TAB] and it would complete to cd www. Brilliant.

It wasn’t quite so easy on the Mac, though. I updated my .profile, but couldn’t get it to work. I thought I had a syntax error in my .profile, but after hours of trial and error, I was no closer. I pinged the #lazyweb on Twitter to ask whether it worked for others on OS X and got more than a few affirmative responses which just confused me even more. A quick chat with Brad Greenlee, though, pointed out the error of my ways. It turned out that CDPATH was working great, but I was assuming (yeah, I know) that tab completion would also work. It didn’t.

For me, something like CDPATH is only useful with tab completion because otherwise, I can tab complete the full path to the file before I can type the entire directory name (for all but the shortest directory names). Besides, the Tab key is completely woven into the fabric of my muscle memory now. I can’t give it up when I’m in the shell. After a little digging, I found the answer:

$ sudo port install bash-completion

Yep, that’s it (assuming you have MacPorts installed). Well, almost. You do have to update your .profile (or .bash_profile, .bashrc, etc.) to source the installed file at /opt/local/etc/bash_completion. Instructions for doing so are printed in the output of the installation. In case you close your window too early, though:

if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi

Happy completing.

Installing MacPorts with tcsh

This evening I’m beginning my foray into the world of Git in order to see what all of the fuss is about. On Mac, the first step was to install MacPorts. That’s also where I ran into my first problem. I don’t know yet whether this is a really nasty omen, but I thought it might be worth documenting the problem and the solution.

I started by downloading the MacPorts package installer; I seldom mess with source code installs without a compelling reason to do so. Once it was downloaded, I ran the installer. This is pretty basic stuff, so when the installer told me it completed successfully, I assumed that it, you know, completed successfully and I tried to install git:

$ sudo port install git-core sudo: port: command not found

Oops. I’m a man; I hate reading instructions, but now I had to. So I visited the MacPorts installation instructions and they assured me that the installer would take care of everything for me:

This procedure will place a fully-functional and default MacPorts installation on your host system, ready for usage. If needed your shell configuration files will be adapted by the installer to include the necessary settings to run MacPorts and the programs it installs, but you may need to open a new shell for these changes to take effect.

I opened a new shell, but it still didn’t work. Evidently, all of this automation only happens if the default shell is bash. My default shell on every Unix (or derivative) box that I spend a significant amount of time logged into is tcsh. I have this set specifically since Mac, like most other Unix variants I’ve used, defaults to bash when a new user is created.

Fortunately, MacPorts documents the shell changes, but even the documentation is bash-centric. It’s an easy translation, though. I added the following lines to my .tcshrc file:

# # Macports environment variables # set MANPATH = `manpath` setenv PATH /opt/local/bin:/opt/local/sbin:$PATH setenv MANPATH /opt/local/share/man:$MANPATH

Once I saved those changes, closed and reloaded my .tcshrc file (e.g. $ source ~/.tcshrc) the system was able to run the port executable.