3

UBuntu 16.04 Bash 4.4

In 4-bash-update.sh line 158:

cd "$drive00" && sudo -H -u myuser bash -c "timeout 2s ./binaryfile -gentoken" > "${save_log_dir}"/update-"${now}".log;
                                                                              ^-- SC2024: sudo doesn't affect redirects. Use ..| sudo tee file

I tried a few times and each time my file gets eaten.

Robert
  • 7,394
  • 40
  • 45
  • 64
Vituvo
  • 1,008
  • 1
  • 9
  • 29
  • What do you mean "eaten"? The command is **supposed to** truncate the output file -- if you didn't want that it would need to be `>>`, not `>`. (It's clear that as-written the code tries to open the output file with original, pre-`sudo` privileges, but if the file is "eaten", that means there were actually enough write privileges there to truncate it, so it's not clear what the issue you want to use `tee` to solve is in the first place). – Charles Duffy Aug 17 '18 at 17:28

1 Answers1

5

You don't need to use tee, just put the redirection inside the command that's executed with bash -c:

sudo -H -u myuser bash -c 'timeout 2s ./binaryfile -gentoken > "$1"' _ "${save_log_dir}/update-${now}.log"

If you redirect outside, your original shell is trying to open the file, but it doesn't have permission. Putting it inside the bash argument executes it in the target user's shell, with their permissions.

The _ in the command line is a dummy value for the $0 parameter of the shell. You need that placeholder to be able to supply the filename as $1.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Agreed; if you have permission to `sudo bash`, you probably don't need `sudo tee` at the same time. Some environments restrict shell access via sudo, and `sudo bash` isn't an option there. Also, if the file write is the only part that requires sudo access, it is more least-privilege to run the command that generates the output without `sudo` and pipe it to `sudo tee [-a] filename`. – Mark Reed Aug 17 '18 at 16:11
  • 2
    Better practice to make that `sudo -H -u myuser bash -c 'timeout 2s ./binaryfile -gentoken >"$1"' _ "${save_log_dir}/update-${now}.log"`, so you aren't substituting data (filenames) into code (the argument to `sh -c`). Sure, the OP probably controls the values of `save_log_dir` and `now`, but better to be in good habits for when operating over uploaded/untrusted/user-provided filenames later. – Charles Duffy Aug 17 '18 at 16:15
  • @CharlesDuffy what is the usage/purpose of the `_` underscore? – nbari Aug 17 '18 at 17:06
  • @nbari, it's a placeholder for `$0`, such that the following argument becomes `$1`. – Charles Duffy Aug 17 '18 at 17:23
  • 1
    @Barmar, ...am I correct in that the single quotes are an attempt to respond to my comment? (Even though there's no edit history, I don't remember seeing them earlier). If so, they don't actually protect against injection attacks; a filename can very much contain a literal `'` character. Consider `touch $'hello\'$(rm -rf ~)\'$(rm -rf ~)'`, creating a name which will perform an injection whether or not such quotes are present. – Charles Duffy Aug 17 '18 at 17:25
  • @CharlesDuffy They were in my original answer, not sure why you didn't see them. I'll use your version. – Barmar Aug 17 '18 at 17:59