Cannot run a program as root because you “Cannot open display”

Say you’re trying a program as root. You sudo, you type the program name and then… bang.

(wireshark:2901): Gtk-WARNING **: cannot open display: localhost:30.0

Here’s the fix: remember the “localhost:30.0”, sudo into a root shell, run xauth to create/merge root’s Xauthority file and use the same display:

sudo -i
xauth merge ~your_username/.Xauthority
export DISPLAY=localhost:30.0

If you don’t get the display name (in the error message) when first running the program, you can retrieve it by echoing $DISPLAY.

String-building performance – a small experiment

I wanted to create a collection of all ASCII letters (both upper- and lowercase) and single digits in Python.

The first (IMO most Pythonic) way that I came up with uses the standard string concatenation operator:

import string
a = string.ascii_letters + string.digits

Then I wondered, would it be faster to use the usual methods to format strings?
Say, a = "%s%s" % (string.ascii_letters, string.digits) or a = "{0}{1}".format(string.ascii_letters, string.digits)?

Only timeit.timeit can tell.

>>> timeit("a = string.ascii_letters + string.digits", setup="import string", number=10000000)
1.4662139415740967
>>> timeit("a = \"%s%s\" % (string.ascii_letters, string.digits)", setup="import string", number=10000000)
2.8996360301971436
>>> timeit("a = \"{0}{1}\".format(string.ascii_letters, string.digits)", setup="import string", number=10000000)
12.925632953643799

Interesting, innit. Now, a word of caution: these results are limited to this particular example. Results may vary (and probably do) if the “domain of the experiment” changes – that is, if you use different strings in terms of number, length, characters, etc.

Change directory like a pro – 5 minutes intro

pushd and popd: it might take a bit to get used to them, but it’s worth it.

The basics

pushd some/path will simply take you to that directory (just as cd some/path does), with the added bonus that the old directory is kept in a FIFO queue.
popd will take you to the last path that was pushed to the queue.

The list of paths populating the queue will be output as soon as you hit either command.
Bonus: use dirs to list the entries in the queue without changing directory.

Sample session:

you@box:~> pwd
/home/you
you@box:~> pushd ..
/home ~
you@box:/home> dirs
/home ~
you@box:/home> pushd ~/bin/
~/bin /home ~
you@box:~/bin> popd
/home ~
you@box:/home>

Additional tips and tricks

  • If you push the same path multiple times… the same path will appear multiple times.
  • Don’t want to see the output? Alias the commands and redirect the output to /dev/null
  • Want to save a few keystrokes? Alias the commands to something like p and o
  • Want to impress your friends? Move around with p [+-]n where n is the number of entries to skip in the queue. Example:
    you@box:~> dirs
    ~ ~/bin ~/bin /home
    you@box:~> p +3
    /home ~ ~/bin ~/bin
    you@box:/home>

    (explanation: with the first command you can see that a) you find yourself in ~, b) the second and third entry is ~/bin, and c) /home is in fourth position. Count 3 from where you are, and you know you’ll land on /home).

Here a nice page that gives you more details on the subject. (I stole the aliases from there :)

Switch the case of words matching a pattern in Vim

Suppose you want to switch lowercase all instances of, say, “IMPORT” in a file.

Of course you can search for the pattern (/IMPORT), then hit gue and then continue by repeating n and . until all occurrences have been changed.

But there’s a smarter way to do that, that leverages :%s, that is :%s/\(IMPORT\)/\L\1/g.
This calls the \L function and applies it to the first matched group (\1).

There’s also a \U function, which, as you may have guessed already, can be used to switch to uppercase.

Some food for thought on the matter can be found on the Vim Wikia and the official Vim doc.

Python snippet of the day – check if a process is running

Quick’n’dirty function in Python to check whether a process is running.
Note: this only works on Linux and requires importing the re module, so YMMV.

For a much much better (that is, OS-agnostic, non-hacky) solution, you should use psutil.

def _isProcessRunning():
    pslist = filter(lambda pid: pid.isdigit(), os.listdir("/proc"))
    try:
        for pid in pslist:
            if re.match(".*%s" % (cmdname,), open(os.path.join("/proc", pid, "cmdline"), "rb").read()):
                return True
    except IOError:
        pass
    return False

Nosetests and the docstrings

For some reason when you use the -v switch in nosetests, instead of using the test name, the runner uses the docstring (and only first line, for that matter).

Solution: install the “nose-ignore-docstring” plugin:
sudo easy_install nose-ignore-docstring
and then enable it by adding:
[nosetests]
with-ignore-docstrings=1

to ~/.noserc

For additional information, I’ll point you to the plugin web page on PyPy.

Debugging shell scripts (Bash)

New job, different technologies, same me, with my head that sometimes can’t remember simple things such as…

The flag to use in order to debug Bash scripts. Here it is:

-x

All it does is echoing back the commands it runs (for those who think it’s not a big deal, remember it expands the variables – one day, when running your script with -x you’ll go “ooh, I didn’t mean to include all those files!”).

Simples. And yet I keep forgetting it. And keep trying random flags (was it -w? Maybe it’s -e…).

Windows server uptime

Quick and easy once you know it, but for me it wasn’t until I spotted a page on the Microsoft support website.

Long story short, there’s no uptime command (I miss you penguin!), but you can get instead the time when the server was booted last time. To do so, open a prompt and type net statistics server.

The line starting with “Statistics since [date] [time]” is what you are looking for.

Now, to get the actual uptime, Powershell is your friend:

$template = 'dd\/MM\/yyyy HH:mm'
$t = [DateTime]::ParseExact("27/04/2014 03:30", $template, $null)
([DateTime]::Now - $t).TotalHours

In this case I copied in the date manually, but of course it can be automated.