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.
4
  • 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", especially codeforester's answer. Commented May 10, 2022 at 1:03
  • Hello Gordon, codeforester's answer worked nicely indeed. I will proceed to answer my query, following codeforester info. Thank you! Commented May 10, 2022 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) Commented May 10, 2022 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). Commented May 10, 2022 at 22:16

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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).
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?
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.
(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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.