0

I want to export the results of a Prodigy tagging session through the command db-out. Prodigy is installed in a Google Compute Engine VM, however, I am not the owner of it and for that reason, what I am attempting, looks like this:

# Assume `test1` exists
DB_NAME="test1"
#  `super_user` is Prodigy owner's home directory.
sudo runuser -l super_user -c 'python3 -m prodigy db-out "$DB_NAME" > ./"$DB_NAME".jsonl'

The previous commands should generate a test1.jsonl file, which should be found in the super_user home directory; however, no test1.jsonl is generated. BTW, when those lines are run, no warning or error is displayed.

Nevertheless, when I directly run the following command:

sudo runuser -l super_user -c 'python3 -m prodigy db-out test1 > ./test1.jsonl'

test1.jsonl file is correctly generated, as expected and explained before. Why?

Additional notes / updates:

  1. There is no need into explaining what the runuser or db-out commands are doing. I think the error is more related to a (possibly?) wrong variable substitution from my side, that I am not seeing right now.
Michael M.
  • 10,486
  • 9
  • 18
  • 34
David Espinosa
  • 760
  • 7
  • 21
  • 2
    Variables aren't expanded inside single-quotes (and having double-quotes inside the single-quotes doesn't change this). See ["Difference between single and double quotes in Bash"](https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash), especially codeforester's answer. – Gordon Davisson May 10 '22 at 01:03
  • Hello Gordon, codeforester's answer worked nicely indeed. I will proceed to answer my query, following codeforester info. Thank you! – David Espinosa May 10 '22 at 21:35
  • 1
    Why `sudo runuser -l super_user` instead of `sudo -u super_user python3 -m prodigy db-out "$DB_NAME" >"$DB_NAME.json"`? Unless you need `super_user` to open the output file, but there are other ways around that (f/e, `| sudo -u super_user tee "$DB_NAME.json" >/dev/null`) – Charles Duffy May 10 '22 at 22:16
  • ...point being, there's a lot less that can go wrong when you don't start a shell as the target account. (If you _need_ the target account's dotfiles, that changes things, but that's a requirement that should be explicitly specified to help drive the choice of implementations). – Charles Duffy May 10 '22 at 22:16

1 Answers1

0

After addressing my attention to this post (which was kindly suggested by Gordon Davidson, and whose revision is highly suggested), I managed to solve my original issue. The corrected code looks like follows:

DB_NAME="test1"
sudo runuser -l super_user -c "python3 -m prodigy db-out $DB_NAME > ./$DB_NAME.jsonl"

Just to make changes clear, they are:

  1. The single quotation marks were replaced by double ones.
  2. The inner double quotation marks were discarded.

Afterwards, the script works as it is supposed to be. If I understand this post correctly, there could be some other valid answers; however this one works for now.

Thank you.

David Espinosa
  • 760
  • 7
  • 21
  • There's security risk here: If you don't control your `DB_NAME` variable closely, contents it contains could be run as a command. (By contrast, in a normal circumstance shell variable expansion can't go through parsing steps other than word-splitting and glob expansion, so any command substitution, redirection, etc. they provide won't be honored). – Charles Duffy May 10 '22 at 22:18
  • Thank you Charles, those commands are usually run "paying a close eye to them" and (as mentioned before in some other answer) always locally, so I don't think security will be a serious issue at the moment. Just curious here: what would be a "safer" approach? – David Espinosa May 10 '22 at 22:32
  • The cause of the problem is performing substitutions into a string that's later parsed as code. If you switched from `sudo runuser -l super_user -c "..."` to `sudo -u super_user ...`, that would avoid it (albeit with some costs). How to avoid the issues associated with that depends on the details; for example, `sudo -u super_user sh -c '"$@" >"$0"' "./$DB_NAME.json" python3 -m prodigy db-out "$DB_NAME"` is one alternative that still gets you the redirection performed as the target user but without substituting into a shell. – Charles Duffy May 10 '22 at 23:49
  • (whereas if you need `super_user`'s dotfiles, it might be `sudo -u super_user sh -c '. ~/.profile && "$@" >"$0"' ...` or similar; this is back to needing to know why `sh -c` looked like the right tool, and thus how to get whichever specific behaviors drove you to choose it). – Charles Duffy May 10 '22 at 23:53