bash: Looping over a range

This falls into the category of things that are simple yet I’m always trying to remember. Sometimes in bash I find myself wanting a for loop, not of the usual foreach type (for i in ls /etc/; do ...), but a more classical one (a la C-style for var=0; var<100; var++ ... syntax). Here's the bash way:

for i in {0..99}; do echo $i done

The output is a list of numbers from 0 to 99. For a fun example of when you might need this, consider the case of noticing that Postfix isn't running on a machine and starting it. Your mail client promptly crashes, and the flurry of output in the log indicates that it's delivering mail as fast as it can, but complaining that some mail has been in the queue for 180 days. "Holy smokes," you exclaim, stopping Postfix. "Just how much mail is there?" You're not entirely sure because you aborted your ls after it sat for a good minute with no output. That's never good. du -sh shows about a gig and a half.

"I've got this under control," you think. rm -f /var/spool/postfix/. Ta-da! Wait, what's this "/bin/rm: Argument list too long" business? That error can't possibly be good. rm very rarely complains. So we tried a smaller delete size, thinking we could do postfix/1, postfix/2*, etc. Just step through it. That, too, was too much for rm.

So it ended up taking an absurd for i in {0..99}; do rm -f /var/spool/postfix/$i; done to purge the mail. (And that didn't catch all of it, either; I'm not sure off-hand how to do this in hex.) Each iteration deleted somewhere around 2,000 mail messages, making me think there were something like a half-million messages. (00-FF, times a little under 2,000.)

Transgender Rights

As the gay marriage debate broils, I’ve been hearing about transgender rights a bit lately. As someone who hasn’t sat down and read a newspaper lately, I was a bit out of the loop. I’d seen it mentioned in passing in a few times, and then one morning there was nothing good on FM radio on my drive into work, so I switched over to AM.

It turns out, by the way, that the AM band is the (almost) exclusive province of conservative talk radio. So I found one radio station that talked about the absurdity of the transgender rights bill, known by some in New Hampshire as the “bathroom bill.” It seems that the bill is to allow transgendered people to use whatever bathroom they like, regardless of whether it’s labeled as Male or Female. That seemed like a pretty ridiculous law to me. The talk radio hosts went on to describe a situation in which your young daughter would be in a public restroom, and then a giant gay man/pedophile would go in after her and you’d be powerless to object, since he’d claim he was transgendered.

But it turns out that you shouldn’t get your news from random far-right talk radio shows on AM radio. I saw another reference to “The Bathroom Bill” in New Hampshire, so I actually looked into it.

First of all, here’s the Transgender Wikipedia page. I think many people (including myself) thought it referred to people who had operations to change their gender. In actuality, it refers to people who were born one gender but but are mentally a different gender, or those “whose identity does not conform unambiguously to conventional notions of male or female roles, but combines or moves between these.”

More significantly, “The Bathroom Bill” is a giant misnomer. The law does little more than plunk “transgendered person” into the middle of the equal rights bill. It makes no mention of bathrooms at all.

But in viewing a discussion of other things right now, someone pointed out a few good points:

  • No one seems to be able to find any law governing bathroom usage now. I don’t believe it’s illegal for a male to go into the lady’s room, or vice versa. Sure, in most cases it wouldn’t go over well, but now imagine a mother going to check on her young son in the men’s room. It’s already legal.
  • You don’t have to prove your gender to use a bathroom or locker room.
  • With status quo (the law not proscribing which bathroom should be used), no one seems to be aware of a single case of a transgendered person causing problems by using the “wrong” bathroom. More directly, no one seems to be aware of a transgendered person ever using the “wrong” bathroom, because it’s a total non-issue.
  • Transgendered people aren’t looking for bathroom equality. The bill has nothing to do with that. They’re looking for protection against people who fire them or otherwise egregiously discriminate against them.

So I didn’t care before. But now I do. Even though I don’t think I’ve ever met anyone transgendered, I’m supporting transgendered rights. I thank the uberconservative talk radio show I happened across for distorting the issues enough to get me interested in the issue.

Politics

Lately I’ve felt that things were going pretty well. I was reading a bit of international news and looking at the international reaction to our presence at the G20 summit, for example. Of course not everyone in the world loves us, but I couldn’t help but feel that our presence was a little different than last time. Our President helped get disagreeing parties to agree, and in general seems to have the world eager to work with us. (I don’t really mean this as a condemnation of Bush, nor is it my intention to heap praise on Obama.)

And then I read what conservatives are saying, and it almost seems like we’re looking at two vastly divergent realities. I see a statesman, they see a closet Muslim who was all too eager to bow to an Arab leader and who went out of his way to apologize for being American. I see a fiscal plan inspired by John Maynard Keynes, they see someone deliberately wasting money for his own gain. I see the first black President, they see the first illegal immigrant President. I see a President who came in after Bush’s first round of financial bailouts and pretty much continued the policy, they see a President who nationalized the banks because he’s a Socialist. Oh, and he wants to take everyone’s guns away, and destroy Christianity.

I’d gone a while without reading the “wingnut propaganda,” and in that time period, I’d come to think that things were pretty good. Obama’s approval rating is something like 70%, and the two parties have been known to work with each other a bit lately, even if it’s been far less than I’d like. (And even if it’s been largely Democrat-led, which doesn’t really make for impressive bipartisanship…) And then I realized that there’s a lunatic fringe that seriously believes he’s a Muslim or a Socialist, and became truly worried. Fiscal conservatives and social conservatives may dislike Obama, and I respect their different views. Divergent views, discussed and brought to compromise, truly leave us better off. But there are thousands, if not millions, of Americans who have literally lost touch with reality. They’re like the MIHOPs of the Democrats.

I also want to caution that when I use terms like “neocon” and “wingnut,” I mean them more literally, not as terms to refer to all Republicans. Similarly, I respect Republicans and hate the artifically-created divide between the parties. What I’m complaining about is the wingnut Republicans who use utter lies to advance their own causes. There are Democrats who do the same, surely, but with Democrats leading Congress and the White House, those people aren’t noteworthy right now.

Anyway, two things have interested me lately. Besides the thousands of dead Americans, one thing that always bothered me about the Iraq War was the exorbitant cost. If the money were spent domestically, it could have gone an amazing distance. The military takes up something like 50% of our spending. So I’m waiting to see what the wing-nut faction of Republicans says. They’ve spent weeks protesting Obama’s Socialist spending. But the Democrats have long complained that the Iraq War is too expensive, and Republicans have argued that not giving the military a blank check amounts of waving the white flag of surrender. So I’m curious where this will go, because it could leave Republicans in an awkward state either way. Hopefully it will just be passed and nasty politics will be left out of it.

But then I was reading this article about how Obama may be looking to get the ball rolling on immigration reform. And the general description of his plan seems to amount to increasing border patrol and cracking down on illegal immigration. During the campaign trail one of the things he discussed was a path to citizenship, but with a pretty steep burden: you’d have to learn English, pay back taxes for as long as you’ve been in the country, pay a fine, and only then would you “get in line, behind everyone who came here legally” to become a citizen. Of course, that was something discussed during the campaign trail. The “official” Administration hasn’t even released a plan yet, but has merely made mention of strengthening border control, and the article is little more than speculation.

Yet some Republican activists have already denounced Obama’s (currently non-existent) plan as “dangerous” and “amnesty.” Seriously.

Promession

After experiencing XKCD’s problem with Wikipedia first-hand, I went from the page on canned air to the page on liquid nitrogen to the page on promession. “What is promession,” you might wonder?

It’s a new alternative to cremation, in which a corpse is frozen with liquid nitrogen until it is so brittle that it can be shattered sufficiently to render it nothing more than a pile of extremely cold dust. It’s then returned to room temperature, allowing all the water in the body to evaporate. (Metals are apparently removed from the body at this point, too.) This dried-out smashed-up body powder is then buried, much like in cremation, only there’s more dust than with cremation. The good news is that it’s eco-friendly.

Prediction: promession is not going to catch on very quickly.

Cleaning up Maple Syrup

Even when I have maple syrup on a plate after breakfast, it’s a pain to get off. But that’s nothing compared to what happens if you spill a few drops of maple syrup in your car’s cupholder and don’t realize until the next day. I ended up leaving it for a few more days because I couldn’t think of a way to get it out. Cleaning it up with a napkin wouldn’t work since it’s far too sticky; scraping it wouldn’t work because it would leave a thin layer behind; cleaning solution wouldn’t help a lot, either. Time for a new car?

Driving home tonight, the perfect solution hit me. Freeze it and then chip it out!

Most of us (myself included) don’t have access to liquid nitrogen, but we have something almost as good: cans of compressed air, meant for cleaning out computers and such. Held perfectly upside down, it sprays a liquid that can cause nasty frostbite.

It wasn’t as easy as I’d hoped, but it was the same general plan: spray a bunch of the stuff on to freeze the crap out of it, then go in with a knife and chip the deep-frozen maple syrup chunks off. (Warning: the stuff is dangerously cold. The can carries a frostbite warning. Don’t touch it!) The problem I ran into is that it would thaw out in a matter of seconds, meaning that I had to spray a ton and then very quickly chip it out. (Because there’s nothing like rushing while you’re weilding a knife and some unknown chemical that’s ridiculously cool.)

Nerd node: The Wikipedia page Gas duster covers the contents of this canned air stuff in great detail, and also mentions something I’m noticing after the fact: they put a bitterant in to keep people from huffing the stuff (I’m not sure why, since it’s toxic?), but it’s much stronger if you hold the can upside down (since you’re basically releasing the liquid before it expands, hence using a much greater quantity). So consider doing this in an open area. At the very least, don’t eat nearby, and whatever you do, don’t end up putting your fingers in your mouth. Trust me.

snoopdogg

I saw someone following a user named “snoopdogg” on Twitter. I thought it was hilarious because the posts are exactly what you might expect Snoop Dogg to tweet: things like “bacc on the blocc what up ma hungry twizzles” and “mad love to everyone out here itz gonna be a dope dizzay.”

But with over 100,000 followers, it seems that snoopdogg really is Snoop Dogg. And in this case, it’s a neat use of Twitter for marketing. He just posted, “4 all ma djs get this track out there download link http://tinyurl.com/cgl2ka” — the link goes to a stream of Snoop Dogg Millionaire, what seems to be a hot-of-the-press new song with someone from Slum Dog Millionaire. I have to say that the song is awful (IMHO), but that’s not the point.

Removing Duplicates from MySQL

I Googled that a while ago. How do you remove duplicate rows from a SQL database? (MySQL specifically.)

If you have a ‘simple’ duplicate setup, it’s pretty easy, and lots of other sites go into great detail. (And in that case, you might look into how to require that fields be unique so you don’t have that problem anymore…)

In our case, we ran into an obscure problem where we expected the combination of two fields to be unique. Without publicizing anything secret, we had a summary table of user_id and month. (Not that it’s actually anything secret, but I refer to the table I did this on as “tablename,” just since blogging about our production database schemas seems like a bad idea…) A brief bug introduced some duplicates. My task? Remove the duplicate rows.

So I went about it somewhat backwards, and started wondering how do a SELECT DISTINCT across two columns. You can’t, really. Someone recommended something clever: CONCAT() across the two field names, and a DISTINCT on that: SELECT DISTINCT(CONCAT(user_id, month))… After toying with that a bit, I was able to create a temporary table housing a de-duped version of our data:

create temporary table nodupes SELECT DISTINCT(CONCAT(user_id, month)) asdf, tablename.* FROM tablename GROUP BY asdf;

But how does that help? The problem with temporary tables is that they’re, uhh, temporary. If you lived on the edge, you could probably “DROP TABLE original_table; CREATE TABLE original_table (SELECT * FROM temp_table)”, but this has a few horrible problems. One is that you’re throwing away all your disk-based data so you can populate it with a version that exists only in RAM. If anything went wrong, you’d lose the data. Furthermore, in our case, this is a live, busy table. Dropping it in production is awful, and it would take many minutes to repopulate it since it’s a huge table.

So then it was clear what I wanted to do: something like DELETE FROM original_table WHERE id NOT IN(SELECT * FROM temp_table_with_no_dupes), except not using an IN() on a table with hundreds of thousands of rows. And this is where it got tricky. The key is to use that temporary table to derive a new temporary table, housing only the duplicates. (Actually, speaking of “the key,” create one in your temporary table: CREATE INDEX gofast ON nodupes(id); — you’ll need this soon, as it’s the difference between the next query taking 10 seconds and me aborting it after 30 minutes.)

The temporary table of duplicate rows is basically derived by joining your ‘real’ table with the list of de-duped tables, with a rather obscure trick: joining where id=NULL. So here’s what I did:

CREATE TEMPORARY TABLE dupes (SELECT tablename.* FROM tablename LEFT OUTER JOIN nodupes nd ON nd.id=tablename.id WHERE nd.id IS NULL);

For bonus points, we’re selecting from the real table, so the silly CONCAT() field doesn’t come through into this temporary table.

So once again, I momentarily flashed a sly grin. This is going to be easy! DELETE FROM tablename WHERE id IN(SELECT id FROM dupes);. But then my sly grin faded. It turns out that there are two problems here. The first is that there are still a lot of rows. In my case, I was doing an IN() with about 6,000 rows. MySQL doesn’t like that. But there’s a bigger problem. (Thanks to Andrew for confirming that this is a real bug: #9090.) MySQL doesn’t use indexes when you use a subquery like that. It seems the bug is pretty narrow in scope, but this is precisely it. So that query is awful, basically doing 6,000 full table scans. And on a really big table.

So the solution comes from something I’ve never even thought about doing before. MySQL calls it the “multi-delete.” I call it the, “Holy smokes, this could go really, really wrong if I’m not careful” delete.

-- Don't run this yet DELETE bb FROM tablename AS bb RIGHT JOIN dupes d ON (d.id=bb.id);

That’s the command you want, but a few caveats. First, change the first line to “SELECT *” and run it to see what happens. Make sure it’s only grabbing the duplicate rows. You’re not able to use a LIMIT in a multidelete query, so you have to be extremely careful here. Second, we tested this multiple times on various test databases before doing it against our master database, and I was still uneasy when it came time to hit enter. Keep backups before you do this. And finally, in many cases, MySQL will expect an explicit “USE database_name” before the multi-delete, where database_name is the database housing the table you’re deleting from. Keep that in mind if you get an error that it can’t find the table, even if you explicitly reference it (via database_name.table_name).

Child Porn and Not-Child-Porn

So I think almost everyone would agree that child porn is awful, and those involved in it should be sent to jail for a really long time.

But there’s a constant barrage of news stories where prosecutors fail to use any common sense at all. A 16-year-old boy might send an explicit photo of himself to a 16-year-old girl, and a school administrator might confiscate the phone and alert police. And then the boy is arrested for creating child porn, the girl is arrested for possessing child porn, and the school administrator who confiscated the phone is also arrested. How does that make any sense at all? In another recent case, two minors (both around 16) videotaped themselves having (consensual) sex and were charged with statutory rape, since both were underage.

I think it’s a case of no one wanting to appear too lax on prosecuting child predators, so no one stops to consider that it makes no sense to arrest children as child predators. Let’s stop arresting children for child porn. And then, let’s get the media to forget the absurd phrase “sexting.” And then maybe law enforcement can start focusing their attention again on creepy old perverts who should be arrested for child porn.

Any time these news stories come up, the response is pretty much universal: “That’s absurd,” or, “They’re making way too big of a deal out of this.” I wish some legislators would have the courage to say the same thing.

Relentless Materialism

A few cool things I’ve found myself looking at today:

  • Leatherman Skeletool. I have one of their old-school multi-tools, but it’s huge. This is a trimmed-down version that looks much slicker.
  • TuneUp, a program to clean up your iTunes libraries. (Found via Uncrate.) It’s supposed to find names for your music to keep things accurately labeled, and also download missing cover art. I haven’t tested it yet, though.