3
votes

I am using a preflight bash script in packagemaker :

run cp -pf "/folder/to/my/db" "/Library/Application Support/app/db

The run function (that I found on StackOverflow by the way) :

run() { $*; code=$?; [ $code -ne 0 ] && echo "command [$*] failed with error code $code\nERROR: $@\n"; }

The command cp returns a 64 code. What is this 64 status please? How can I resolve that?

1
Welcome to Stack Overflow. Please identify where you found the run function on SO so that we can go and fix it. And I'm sorry you got misled by a bogus (or partly bogus) answer elsewhere.Jonathan Leffler
herearnaud
OK: I'd just found Bash: echoing the last command run as a possibility too, and was coming back to ask. I will go perform surgery. […time passeth…] Surgery performed. +1 for researching on SO, and for allowing us to fix a problem.Jonathan Leffler
this website is amazing :)arnaud

1 Answers

4
votes

The problem is that you don't have a folder Support/app/db for the command to copy files /folder/to/my/db and /Library/Application to.

Replace the misguided (almost always wrong) $* with the correct "$@":

run()
{
    "$@"
    code=$?
    [ $code -ne 0 ] && echo "command [$*] failed with error code $code\nERROR: $@\n"
}

Plain $* breaks words at spaces; "$@" preserves spaces in arguments. Most often, $* is not the right notation (though it would be fine in the echo where you used $@). It isn't clear to me why the command's arguments are being listed twice in the error message.


The error reporting would be improved by adding >&2 to the end to redirect the output to standard error, which is where error messages belong. (I'd remove the repetition while I'm at it.) Note that using $* inside the argument to echo is entirely appropriate.

    [ $code -ne 0 ] && echo "command [$*] failed with error code $code" >&2

In fact, the run() function can be simplified still more; the variable code really isn't needed:

run()
{
    "$@" || echo "command [$*] failed with error code $?" >&2
}

If you want the script to exit too, then you can use:

run()
{
    "$@" || { echo "command [$*] failed with error code $?" >&2; exit 1; }
}

The { ...; } notation treats the commands within as a unit for I/O redirection without starting a sub-shell.


See also How to iterate over arguments in a Bash script.