diff --git a/Makefile b/Makefile
index c49d2ee..e3882bc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 all: sxiv
 
-VERSION=git-20110301
+VERSION=git-20110303
 
 CC?=gcc
 PREFIX?=/usr/local
diff --git a/commands.h b/commands.h
index d455fac..cb14fe6 100644
--- a/commands.h
+++ b/commands.h
@@ -1,29 +1,13 @@
-#define FILENAME (const char*) 0x1
-
 typedef struct {
 	KeySym ksym;
-	const char **cmdline;
 	Bool reload;
+	const char *cmdline;
 } command_t;
 
-static const char *cmdline_1[] = {
-	"jpegtran", "-rotate", "270", "-copy", "all", "-outfile", FILENAME,
-	FILENAME,	NULL };
-
-static const char *cmdline_2[] = {
-	"jpegtran", "-rotate",  "90", "-copy", "all", "-outfile", FILENAME,
-	FILENAME, NULL };
-
-static const char *cmdline_3[] = {
-	"mogrify", "-rotate", "-90", FILENAME, NULL };
-
-static const char *cmdline_4[] = {
-	"mogrify", "-rotate", "+90", FILENAME, NULL };
-
 static command_t commands[] = {
-	/* key            command-line      reload? */
-	{  XK_a,          cmdline_1,        True },
-	{  XK_s,          cmdline_2,        True },
-	{  XK_A,          cmdline_3,        True },
-	{  XK_S,          cmdline_4,        True },
+	/* key          reload?  command, '#' is replaced by filename */
+	{  XK_a,        True,    "jpegtran -rotate 270 -copy all -outfile # #" },
+	{  XK_s,        True,    "jpegtran -rotate 90 -copy all -outfile # #" },
+	{  XK_A,        True,    "mogrify -rotate -90 #" },
+	{  XK_S,        True,    "mogrify -rotate +90 #" }
 };
diff --git a/main.c b/main.c
index e3a1fa2..d736d12 100644
--- a/main.c
+++ b/main.c
@@ -273,57 +273,59 @@ void read_dir_rec(const char *dirname) {
 	free(dirnames);
 }
 
-int run_command(const char **cmdline, Bool reload) {
-	int argc, i;
-	const char **argv;
+int run_command(const char *cline, Bool reload) {
+	int fncnt, fnlen;
+	char *cn, *cmdline;
+	const char *co, *fname;
 	pid_t pid;
-	int error, ret, status;
+	int ret, status;
 
-	if (!cmdline)
+	if (!cline || !*cline)
 		return 0;
 
-	argc = 1;
-	while (cmdline[argc-1])
-		++argc;
+	fncnt = 0;
+	co = cline - 1;
+	while ((co = strchr(co + 1, '#')))
+		++fncnt;
 
-	if (argc < 2)
+	if (!fncnt)
 		return 0;
 
-	argv = (const char**) s_malloc(argc * sizeof(const char*));
-	error = ret = 0;
+	ret = 0;
+	fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
+	fnlen = strlen(fname);
+	cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) *
+	                                sizeof(char));
 
-	for (i = 0; i < argc; ++i) {
-		if (cmdline[i] != FILENAME)
-			argv[i] = cmdline[i];
-		else
-			argv[i] = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
-	}
-
-	if ((pid = fork()) == 0) {
-		execvp(argv[0], (char **const) argv);
-		warn("could not exec %s", argv[0]);
-		exit(1);
-	} else if (pid < 0 && !options->quiet) {
-		warn("could not fork. command line was:");
-		error = 1;
-	} else if (reload) {
-		waitpid(pid, &status, 0);
-		if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
-			ret = 1;
-		} else if (!options->quiet) {
-			warn("child exited with non-zero return value: %d. command line was:",
-			     WEXITSTATUS(status));
-			error = 1;
+	/* replace all '#' with filename */
+	for (co = cline; *co; ++co) {
+		if (*co == '#') {
+			*cn++ = '"';
+			strcpy(cn, fname);
+			cn += fnlen;
+			*cn++ = '"';
+		} else {
+			*cn++ = *co;
 		}
 	}
-	
-	if (error) {
-		for (i = 0; i < argc && argv[i]; ++i)
-			fprintf(stderr, "%s%s", i > 0 ? " " : "", argv[i]);
-		fprintf(stderr, "\n");
-	}
+	*cn = '\0';
 
-	free(argv);
+	if ((pid = fork()) == 0) {
+		execlp("/bin/sh", "/bin/sh", "-c", cmdline, NULL);
+		warn("could not exec: /bin/sh");
+		exit(1);
+	} else if (pid < 0) {
+		warn("could not fork. command line was: %s", cmdline);
+	} else if (reload) {
+		waitpid(pid, &status, 0);
+		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+			ret = 1;
+		else
+			warn("child exited with non-zero return value: %d. command line was: %s",
+			     WEXITSTATUS(status), cmdline);
+	}
+	
+	free(cmdline);
 	return ret;
 }