Archive

Posts Tagged ‘tips+tricks’

Wrong usage of LD_LIBRARY_PATH
1 star2 stars3 stars4 stars5 stars
(no votes yet)
Loading ... Loading ...

October 19th, 2009 4 comments

Lots of programs that bring their own libraries use the following snippet in their wrapper scripts:

export LD_LIBRARY_PATH="/my/special/librarypath:$LD_LIBRARY_PATH"

This allows linker to find the needed libraries, even if they are not located in the standard directories (which are defined by /etc/ld.so.conf). At first, this seems OK, but it creates one problem, though. When the $LD_LIBRARY_PATH was empty before the assignment, the new value ends with a colon. When we run the program wrapper, linker splits the variable into substrings and ends up with one empty path. This indicates to search for libraries in the CURRENT working directory, which can cause problems or even a security threat.

So, what’s the correct way of defining the library path? Of course, we could check if the variable is empty before the assignment like this:

if [ -n "$LD_LIBRARY_PATH" ]; then
    export LD_LIBRARY_PATH="/my/special/librarypath:$LD_LIBRARY_PATH"
else
    export LD_LIBRARY_PATH="/my/special/librarypath"
fi

but there is one neat shell trick we can use (should work on all POSIX shells). The description says:

${parameter:+word}
Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

In the end we have:

export LD_LIBRARY_PATH="/my/special/librarypath${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

which is not much longer than the line we started with, but does the assignment correctly. (The first colon belongs to shell syntax, the second one is a part of the value being appended).

The Ugly Duckling called $XDG_CONFIG_HOME
1 star2 stars3 stars4 stars5 stars
(no votes yet)
Loading ... Loading ...

March 29th, 2009 4 comments

Let’s take a look into my home directory:

[stick@spectra 0 ~] ls -F
Applications/  Documents/  google.txt    reverse-ssh*
Desktop/       Downloads/  public_html/  work/       

[stick@spectra 0 ~] ls -AF
.0verkill             google.txt              public_html/
.adobe/               .grails/                .pulse/
.android/             .gstreamer-0.10/        .pulse-cookie
Applications/         .gtk-bookmarks          .pyhistory
.AtomicWorm/          .gtkrc-2.0-kde4         .qt/
.bash_history         .gvfs/                  .rawstudio/
.bashrc               .hplip/                 .recently-used
.bouml                .htoprc                 .recently-used.xbel
.boumlrc              .hugin                  .repoconfig/
.bzr.log              .icedteaplugin/         reverse-ssh*
.cache/               .inkscape/              .rnd
.cddb/                .inputrc                .rpmpatch_macros
.cedega/              .IntelliJIdea80/        .rpmpatch_rpmrc
.civclientrc          .IntelliJIdea8x/        .scummvmrc
.civserver_history    .irssi/                 .signature-gk2
.config/              .java/                  .signature-gmail
.crack-attack/        .JxBrowser/             .signature-suse
.cxgames/             .kde/                   .skel/
.darkplaces/          .kde4/                  .Skype/
.dbus/                .kderc                  .smc/
.designer/            .kinorc                 .springrc
Desktop/              .ktorrent.lock          .sqlite_history
.directory            .lbrc.conf              .ssh/
.dmrc                 .lesshst                .strigi/
Documents/            .links/                 .subversion/
Downloads/            .liquidwarrc            .teeworlds/
.dvdcss/              .local/                 .thumbnails/
.eclipse/             .loki/                  .thunderbird/
.emacs                .macromedia/            .ufrawrc
.esd_auth             .mc/                    .ultramixer/
.fbhighlevelshistory  .mcop/                  .vendetta/
.fbhighscores         .miro/                  .viminfo
.fblevels/            .mixxxbpmscheme.xml     .vimrc
.fbrc                 .mixxx.cfg              .VirtualBox/
.fontconfig/          .mixxxmacros/           .vlc/
.fonts/               .MixxxMIDIBindings.xml  .vnc/
.fonts.conf           .mixxxtrack.xml         .w3m/
.gajim/               .mozilla/               .Wammu
.gconf/               .mplayer/               .wapi/
.gconfd/              .mysql_history          .windows-label
.gegl-0.0/            .mysticmine             .wine/
.gem/                 .netxrc                 .winetrickscache/
.gimp-2.6/            .nexuiz/                work/
.gitconfig            .ooo3/                  .Xauthority
.gnome/               .opera/                 .xim.template
.gnome2/              .osc_cookiejar          .xine/
.gnome2_private/      .oscrc                  .xsession-errors
.gnupg/               .profile                .y2usersettings
.google/              .psi/
.googleearth/         .psql_history

Out of 148 entries in my $HOME, there are only 12 of them I really want to see! How much nicer would it be, if it looked like this:

[stick@spectra 0 ~] ls -AF
Applications/  Documents/  public_html/    .signature-gmail
.config/       Downloads/  reverse-ssh*    .signature-suse
Desktop/       google.txt  .signature-gk2  work/

This is very simple to achieve, if only applications followed the XDG Base Directory Specification. Unfortunately, lots of them don’t. When you start using the following piece of code in your new awesome applications:

config = getenv("XDG_CONFIG_HOME")
if (!config) config = getenv("HOME") + "/.config"
config = config + "/my_awesome_app"

instead of the old-school one:

config = getenv("HOME") + "/.my_awesome_app"

users will gain two great advantages with nearly no extra effort:

  • trying application without overwriting the existing configuration
    XDG_CONFIG_HOME=/tmp/ my_awesome_app
  • maintaining multiple configurations of the same application
    XDG_CONFIG_HOME=~/.config/awesome3 my_awesome_app

So, please, don’t ignore the ugly duckling called $XDG_CONFIG_HOME, I’m sure it will mature into a beautiful swan. :)

Image with rounded corners (using CSS3)
1 star2 stars3 stars4 stars5 stars
(votes: 8, avg: 3.88)
Loading ... Loading ...

March 26th, 2009 23 comments

W3C added nice new options for creating rounded corners of elements to their CSS3 working draft. Engines like Gecko, KHTML and WebKit already implemented these functions, but they use vendor prefixes in the keywords (-moz-border-radius, -khtml-border-radius and -webkit-border-radius respectively), because the feature is not yet fully standardized. That’s also the reason why Opera and Internet Explorer decided not to implement this extension for now.

I was playing with the rounded corners and I like this feature a lot, but I also hit one problem (in all 3 engines). When you use the border-radius with an img element, the image is drawn above the border, so it isn’t rounded (left example). Fortunately, the effect could be easily achieved by rounded div, setting its dimensions exactly to the image size and using the image as the div‘s background (right example).

rounded img rounded div
<img style="border: 2px solid black;
            border-radius: 30px;
            -moz-border-radius: 30px;
            -khtml-border-radius: 30px;
            -webkit-border-radius: 30px;"
            src="presov.jpg" />
<div style="border: 2px solid black;
            border-radius: 30px;
            -moz-border-radius: 30px;
            -khtml-border-radius: 30px;
            -webkit-border-radius: 30px;
            width: 180px;
            height: 240px;
            background: url('presov.jpg');" />

Update#1: I reported the issue to Gecko, KHTML and WebKit bugzillas.

Update#2: Dave Hyatt closed the WebKit bug with the comment: “This was fixed recently.” \o/

Tags: , ,

Parallel command execution with limits
1 star2 stars3 stars4 stars5 stars
(no votes yet)
Loading ... Loading ...

February 16th, 2009 No comments

Randy_sk asked today on IRC if we had any idea how to run commands in parallel, but he also wanted to limit the number of the concurrent processes. I immediately responded: “use make”. I started to shape my idea further until I came to this Makefile:

tasks := $(shell seq -s ' ' 1 `cat commands.txt | wc -l`)

all: $(tasks)
    @echo Done

%:
    @echo `sed '$@!d' commands.txt`
    @eval `sed '$@!d' commands.txt`

This expects you had the file commands.txt prepared, which contains one command per line. If you want to call the same command over and over again, just replace commands.txt with values.txt and eval with the command you want to run.

Using this approach you can limit both the number of concurrent jobs: make -j 5 and the maximum load: make -l 2

Others ideas were to use the shell with & and wait, or to use the following one-liner:

while sleep 1; do [ "`ps ax | grep your_cmd | wc -l`" -gt 6 ] || your_cmd &; done

but I really like mine solution the most :D