Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I’m confused why your correct rm examples include $@ twice. Do you mind explaining?

I’ve been bitten by $@ and —- related mistakes at roughly the same time within the last month or so. Luckily nothing to do with sudo.



    su root -c 'rm "$@"' -- "$@"
The first instance ('rm "$@"') is part of the argument to -c. It is the "command" that su will have the spawned shell execute. The single quotes around the entire command pass the whole command, unchanged, onward to the shell that will be spawned, so that what is executed by that spawned shell is rm "$@" .

The second instance is the argument list being given to su by the shell running the su, and it is just normal "$@" semantics there. One has to realize here that the second "$@" is being expanded by the current shell (the one running su) while the first "$@" is not expanded by the current shell, but is instead expanded by the spawned shell.

The "$@" is needed twice, because two expansions ultimately take place, the first expansion occurs in the current shell, the second one is delayed and occurs in the spawned shell.


I had to read this several times before it sunk in, and in fact had to start formulating a follow up question before the bulb turned on.

The first expansion is in the first process, second expansion in the child. So $@ number two is the input to $@ number one.


This one, probably:

    # CORRECT
    su root -c 'rm "$@"' -- "$@"
    rm "one two" "three four"
The command is going to be evaluated by bash, with ARGV set to what you pass after the hyphens as arguments to the bash environment that su spawns. Passing the arguments to su using "$@" to encode your calling function’s ARGV ensures that they’re uncorrupted into the su-spawned bash environment’s ARGV, and then executing the literal command rm "$@" ensures that they’re uncorrupted into the spawned rm command’s ARGV.

You could fake this with printf %q if you tried hard enough but that’s a high-risk game to diagnose issues with, for example when you’re trying to figure out why newlines are reaching the command as the letter n.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: