Coding

Bash: Multiline Eval

Maybe this is obvious to all the linux and bash-fu experts out there, but I just discovered it, thought it was pretty cool and worth sharing for anyone else who isn't quite a bash expert.

Background

Ok, so bash has a feature which takes the output of a command and runs it (no, this isn't the part that's new to me ;), I'll get to that part in a bit). Let's use the print working directory command as an example:

$ cd ~ $ pwd /home/my-user-name

Now let's get a command that just simply outputs the command we want:

$ echo pwd pwd

And then bash's basic feature to execute that result (two different ways to do it):

$ `echo pwd` /home/my-user-name $ eval $(echo pwd) /home/my-user-name

Alright, neat, but basic stuff.

The Problem

Unfortunately, that trick only works when you're evaluating a single line. Try to evaluate multiple lines and it won't work. (The newlines get converted to spaces and it all gets interpreted as one command.)

To demonstrate, let's make a basic script:

$ touch display-a-command $ my-favorite-editor display-a-command

Copy-paste, save and exit:

#!/bin/bash echo pwd echo pwd

Then:

$ chmod +x display-a-command $ ./display-a-command pwd pwd

Ok. So we have a basic command that outputs two lines of commands. Try to evaluate (You get the same result using either eval method):

$ `./display-a-command` /home/my-user-name

Fucknuggets. It only ran "pwd" once. The two lines got mashed together into one line and bash really executed the single command pwd pwd. The second "pwd" was ignored as an unused argument to the first "pwd". That's not at all what we wanted.

The Cool Part

Turns out there's an easy way to do a multi-line eval:

$ eval "`./display-a-command`" /home/my-user-name /home/my-user-name

Yup. That's it. The internal `./display-a-command` evaluates to our two-line command, and the double-quotes ensure the newline gets preserved when passed to eval.

It even works when display-a-command's output includes backticks and quotes:

$ cat display-a-command2 #!/bin/bash echo \`echo pwd\` echo eval \"pwd\" $ chmod +x display-a-command2 $ ./display-a-command2 `echo pwd` eval "pwd" $ eval "`./display-a-command2`" /home/my-user-name /home/my-user-name

Nice. Cool, huh? At least I think it is, anyway.

Read more


Windows Equivalent of sudo

Yea, yea, I know what day today is. And NO, this post isn't some idiotic prank (or any prank at all, for that matter). Irritating psuedo-holiday...

I'd been a Windows guy most of my life, but lately (for various reasons) I've gravitated more to Linux. (Not that I consider any OSes to be all that fantastic). One thing that's quite handy in Linux is the "Don't give me this 'access' shit, I bought and own your circuit board ass, so fucking do what I tell you to" command: sudo.

Last few versions of Windows have started getting uppity about access privileges, so I've occasionally run into a similar need. For example, logging in as an Administrator, firing up an Administrator-priveledge command line, and still getting "access denied" shit from one CLI tool or another regarding files and paths I know damn well I have full access to.

As can probably be expected, the Windows equivalent is all goofy, verbose and awkward (and launches the provided command in a separate auto-closing windows, gee thanks), but at least it's there:

runas /profile /user:YourUserName "C:\Full\Path\To\Program.exe Your Args Here"

Make sure to properly escape anything in those double-quotes (whee...I miss sudo already...). And...oh yea, your PATH won't work here, so you need to know the full path to your program. Luckily, there's an equivalent to "which". Side note: I don't know why that's calling it "where.bat", it behaves more like Linux "which" (shows the path to the one program that would actually get run) than the built-in Windows "where" (shows all programs on the PATH with the given name).

REM This is 'which.bat' @setlocal @set P2=.;%PATH% @for %%e in (%PATHEXT%) do @for %%i in (%~n1%%e) do @if NOT "%%~$P2:i"=="" echo %%~$P2:i

Toss that into a "which.bat", save to your windows directory (yea, not real clean, but hey, it's Windows, I don't give a crap), and get your work done:

> doshit now Fuck off, access denied > sudo doshit now I'm Windows, I don't understand that > which doshit C:\Some\Big\Path\doshit.bat > runas /profile /user:MyUserName "C:\Some\Big\Path\doshit.bat now" Oh, snap!

Read more


(Not so) Fun with C

Ever feel nostalgic for the languages of the good ol' days?

$ cat crypt_poop.c #include <stdio.h> #include <crypt.h> void main() { // Bad input. I wonder what happens...? char* hash = crypt("pass", "$salty"); printf("%s\n", hash); } $ gcc crypt_poop.c -lcrypt && ./a.out Segmentation fault

Me neither.

Read more


Static Checks vs Templates: Always Instantiate Your Templates

One of the key benefits of static typing is the compile-time checking it enables. Compile your program successfully, and entire classes of programmer errors are guaranteed not to exist - regardless of how thorough your unittests are. (Unittests can't realistically be as thorough as static compiler checks. They're an important supplement to static compile-time checks, but not a replacement for them.)

Unfortunately, templates leave a slight hole in this system of guarantees. By the very nature of templates, the code inside cannot be compiled unless the template is actually instantiated. And if the code isn't compiled, it can't be statically checked (beyond mere syntax checks, anyway).

So you're left with this potential scenario: You write a new template in some library, or make some changes/additions to an existing template, then try out your test project and unittest suite. Everything compiles and runs successfully, so you commit your changes and push to the VCS server. Another coder pulls your work, tries to use your template...and gets compiler errors.

Oops! Your test project, or your unittest suite, never actually used the template! Or maybe it only used one instantiation and never attempted other instantiations that were intended to work. Your user became the first one to actually attempt compiling your code, and became the first to discover it didn't work.

Due to the nature of templates, it's impossible for the compiler to test all possible instantiations of a template to ensure they compile (or don't compile, in some cases) as expected, particularly if the template is part of a library. With sufficient sophistication, it may be possible for a compiler to guess at a few sets of arguments that satisfy your template's parameter constraints and then check that they compile. But even D doesn't currently do that.

The moral of this story: Always instantiate your templates. Make sure you always have at least some dummy instantiations that are expected to work. Here's an example of doing it in D:

struct FooType(T) { ... } private alias test_FooType = TypeTuple!( FooType!int, FooType!string, FooType!char ); void fooFunc(T)() { ... } private alias test_fooFunc = TypeTuple!( fooFunc!int, fooFunc!string, fooFunc!(FooType!int) );

It's better, of course, to unittest them. (Tip: It can often help to use foreach over a TypeTuple of the instantiations you want to unittest.) But at the very least, be sure to have some basic instantiations. It's only a one-liner, after all, and may very well save you some embarrassment.

Read more


A Decade Plus Later and HTML/CSS is Still Schizophrenic Crapware

After more than a decade of web development, I'm of the firm belief that HTML and CSS are fundamentally flawed dog shit and in desperate need of a ground-up replacement. And no, HTML5 does nothing to change my mind.

There are many, many reasons for this and I won't attempt to build a full case right now, but here's the latest bit of HTML "fun" I've hit:

html-is-shit.html:

<!DOCTYPE html> <html> <body> <div style="width: 90%"> <table> <tr> <td>Short</td> <td> A little bit of text. Mobile browsers use small font. </td> </tr> <tr> <td>Long</td> <td> Lots of text. Mobile browsers use big font. Lots of text. Mobile browsers use big font. Lots of text. Mobile browsers use big font. Lots of text. Mobile browsers use big font. Lots of text. Mobile browsers use big font. Lots of text. Mobile browsers use big font. </td> </tr> </table> </div> </body> </html>

Notice there is nothing to change font sizes. And yet, when viewed in various popular mobile browsers (such as the Android versions of Firefox and Chrome) not only is the basic font size absurdly small - much smaller than the browser's normal default, but ONE of the cells uses a completely different font size than the rest!:


(click to enlarge)

And no, setting [-whatever]-text-size-adjust: 100% doesn't fix this issue, nor does explicitly setting all font sizes to 1em.

Safari on iPhone, as is typical for Apple, also has it's own...uhh, "creative" interpretation of basic sense: The different columns use different font sizes.

Seriously, what the fuck?! And people actually want to write their applications in HTML?

Read more


Fanning the Code Convention Flames: Parens After Keywords

Much like the famed spaces vs tabs, there are differing preferences about whether to put a space between a keyword and any following parenthesis:

if(condition)... //vs if (condition)...

I submit that including the space is a stupid convention unless you also handle functions the same way:

void foo (int a) {} foo (4);

Which, of course, is rarely ever done, even in codebases that always put spaces after keywords like if.

Read more