4

There are several commands I want to always run in the background. to do so, I added a function to my .bashrc file that runs a command with its arguments in the background, and created some aliases for the commands I want.

Here's a snippet from my .bashrc:

alias tkdiff="CMD=tkdiff; run_bg"
alias meld="CMD=meld; run_bg"

# Run command in background
run_bg() {
    $CMD $@ &
}

The problem is that when I use these commands, if I run the jobs command or when one of the processes is done, all I can see is $CMD $@, and I can't see what's really running or what finished running.

For example:

[ ***** ]$ meld; meld; meld
[1] 117438
[2] 117439
[3] 117440
[ ***** ]$ jobs
[1]   Running                 $CMD $@ &
[2]-  Running                 $CMD $@ &
[3]+  Running                 $CMD $@ &
[ ***** ]$ jobs
[1]   Done                    $CMD $@
[2]-  Done                    $CMD $@
[3]+  Done                    $CMD $@
[ ***** ]$

I tried setting this up without a function (alias meld="meld $@ &"), but then I get missing arguments. I tried creating a string that contains everything in a new var, but then I see the new var's name instead. I tried redirecting it into a file and running it as a script, but then I see the file's name instead. I tried with exec, but I got the same results. I tried using the function with arguments, but I got lots of errors and no results (I was probably doing something wrong).

I know I can write a function for each command, but that's a bad solution and I still see the arguments as $@.

Is there a way to see the contents of the variables instead of their names? Is there a better/easier way to make specific commands to always run in the background?

Using Red Hat 6.0 with GNOME 2.28.2. It's my workplace, so I can't switch distros or anything like that.

Thanks!

YMI
  • 165
  • 1
  • 10
  • Why don't you just do `alias meld='meld &'`? – gitaarik Jan 15 '14 at 11:48
  • It doesn't work. If I'll define it that way, if I execute `meld a b`, I'll get `meld & a b`, which means meld doesn't get his arguments and the arguments become illegal input for the shell. – YMI Jan 15 '14 at 13:26
  • It seems like a lot of effort to get right simply to avoid having to type `&` at the end of a command. – chepner Jan 15 '14 at 16:37
  • It's a lot of effort because it's not as easy as in tcsh: `alias tkdiff 'tkdiff \!:* &'` – YMI Jan 16 '14 at 11:27

2 Answers2

2

I found a solution. Here's the code:

alias tkdiff="run_bg /usr/bin/tkdiff"
alias meld="run_bg /usr/bin/meld"

# Run command in background
run_bg {
    eval "$@ &"
}

Eval dereferences the variables into a string before running, so the text appears fully. It requires for the full command path to be entered manually, but that's good enough.

Thanks to everyone who tried to help!

YMI
  • 165
  • 1
  • 10
  • won't work in this case: `meld "file 1 with spaces" "file 2 with spaces"` – glenn jackman Jan 16 '14 at 13:43
  • It works like this: `meld 'file\ 1' 'file\ 2'` for "file 1" and "file 2". Not very convenient, but file names should have no spaces in the first lace. – YMI Jan 19 '14 at 07:31
  • If you want to live with that, that's your choice. Or you could code it properly and not have to worry about it. – glenn jackman Jan 19 '14 at 16:51
  • "Code properly" depends on my needs. I need to see what's running all the time, but I almost never need to work with file names with spaces. If anyone has different priorities, he can "code properly" to his needs. – YMI Jan 20 '14 at 17:28
1

You can't put parameter variables in an alias. You need a function:

meld() { command meld "$@" & }
tkdiff() { command tkdiff "$@" & }

If you don't want a bunch of mostly identical functions, generate them:

# automatically background the following commands
for cmd in meld tkdiff; do
    eval "$cmd () { command $cmd \"\$@\" & }"
done

To do what you want with aliases, you probably need to do something like:

alias meld='run_bg meld'
run_bg () {
    local cmd=$1
    shift
    command $cmd "$@" &
}
# or, less clear but the same functionality:
# run_bg () { command "$@" & }
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • You repeated the code I posted myself. This keeps printing `$@` instead of the arguments and it means I have to create a new function for each command - Both of them mentioned in my post as something I don't want. – YMI Jan 15 '14 at 13:35
  • I don't see how creating a bunch of functions is worse than creating a bunch of aliases, especially if the functions actually work like you want. – glenn jackman Jan 15 '14 at 14:56
  • Note the importance of using `"$@"` versus `$@` -- the latter won't handle arguments containing spaces properly. – glenn jackman Jan 15 '14 at 15:18
  • I missed the point that each function is instead of the alias. – YMI Jan 16 '14 at 12:07