18

I've been searching everywhere and I've come to believe that there is no way to do that other than having global variables but I believe the guru's in stackoverflow.com may be able to help me:

Is there any way in bash to trap a function by passing arguments to it?
For example, trap <function_name> <arg_1> <arg_2> SIGINT?

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Kounavi
  • 1,090
  • 1
  • 12
  • 24

3 Answers3

32

trap lets you specify an arbitrary command (or sequence of commands), but you have to pass that command as a single argument. For example, this:

trap 'foo bar baz | bip && fred barney ; wilma' SIGINT

will run this:

foo bar baz | bip && fred barney ; wilma

whenever the shell receives SIGINT. In your case, it sounds like you want:

trap '<function> <arg_1> <arg_2>' SIGINT
Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Actually it didn't work since calling trap "myfunction $arg_1 $arg_2" SIGINT SIGTERM meant that when Ctrl-C was pressed the old values of $arg_1 $arg_2 where preserved and not the updates ones. Guess I'll use a wrapper function or make the arguments global since I can't make that work the way I intended to :/ P.S.: Does it matter that I used double_quotes and not single as in your example? – Kounavi Feb 29 '12 at 21:50
  • 1
    @Kounavi: As you guessed -- you need to use single-quotes, not double-quotes. – ruakh Feb 29 '12 at 22:10
  • Yeap! Single quotes did the job! Probably my plugin in gVim needs to be updated because I have bash support and I thought it would be "colored properly" if it was correct. Mucho gracias pal! :) – Kounavi Mar 01 '12 at 12:34
  • 1
    @Kounavi: You're welcome! To clarify, single-quotes and double-quotes both delimit strings, but double-quotes allow backslash-processing and parameter-expansion within the string, whereas single-quotes do not. So, for example, if the variable `$x` is an asterisk, then `echo $x` lists files in the current directory, `echo "$x"` prints an asterisk, and `echo '$x'` prints a dollar sign and an X. – ruakh Mar 01 '12 at 12:50
  • Thanks! I'll keep that in mind too since it sounds useful information :] – Kounavi Mar 01 '12 at 15:16
  • It would be useful to know what scope the code given to `trap` is being run in i.e. if one can pass local variables this way. – Piotr Dobrogost Feb 13 '14 at 14:09
  • Is it possible to pass the exit code or check the exit code inside the trap function? – CMCDragonkai Jul 02 '15 at 11:20
  • The exit code of X where X is in `exit X`. But I figured it out. Just use `$?`. – CMCDragonkai Jul 02 '15 at 17:59
3

Maybe I'm misunderstanding you, but ... this is legal:

trap "cp /etc/passwd $HOME/p" SIGINT
trap 'cp /etc/passwd /tmp/p; echo wooo hoo' SIGINT
rsaw
  • 3,315
  • 2
  • 28
  • 30
  • Only single quotes worked with variables of type $arg1, $arg2 etc. But, yes that's what I needed! ;) – Kounavi Mar 01 '12 at 12:35
  • 1
    I'm glad Michal explained it so thoroughly and that you got it worked out. :) – rsaw Mar 01 '12 at 20:37
1

I'm not sure I understand correctly what you mean, but if you want to make a signal handler call a function and pass it parameters, trap "function arg1 arg2" SIGNAL should work. For example trap "ls -lh /" INT will cause Ctrl+C in your shell to result in ls -lh / (program with 2 args) being called.

Michał Kosmulski
  • 9,855
  • 1
  • 32
  • 51
  • Actually I was not using quotes and it was not working. Thanks for your help :] – Kounavi Feb 29 '12 at 18:59
  • Update: Still it doesn't (check my comments in top post) – Kounavi Feb 29 '12 at 21:53
  • 5
    Just change double to single quotes and the expansion will be delayed until the trap command is executed, for example with `trap 'echo "$PATH"' INT` any changes to PATH will be visible to the trap function. – Michał Kosmulski Feb 29 '12 at 22:00