-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serializing with "$(printf %q "$VARIABLE")" #20
Comments
Interesting. Where can I get the specifics of how this works? |
Of
For the exact specifics:
|
Cool. This sounds like a good tip that some people might want to wrap in a more explanatory function if they use it a fair amount in their script. |
Actually, can you give some examples where it's useful to be serializing... including the xargs example, but specifically other cases. |
Saving variables in a generated script, or a list of environment variables like an app's .profile.d/app-env.sh in buildstep/herokuish (which reminds me of another tip/trick for the High Codex). |
I think I understand what you mean, but some real examples to point me at would be helpful. |
I showed you yesterday how it's used in Pluchu to preserve argument quoting when reproducing the input arguments for ssh's command on the server: https://github.com/plushu/pluchu/blob/master/pluchu#L57 As you could probably guess, Plushu uses it when saving config variables: https://github.com/plushu/plushu-config/blob/master/subcommands/set#L65 Plushu's startup plugin also uses it to export the environment when creating its Upstart unit (but not its systemd unit, I think because systemd doesn't have the same quoting rules as the shell): https://github.com/plushu/plushu-startup-deploy-all/blob/master/install#L24-26 |
Yeah, I get the second two, but I was pretty sure it's unnecessary for the first case as long as it's quoted |
Unfortunately, it is, because You can test this yourself:
will output:
because it will hit the server as:
|
So that is a special case for SSH wonkiness. |
Or really any situation where you're going to pass a command on to a shell (such as |
Alright, I'll have to try this more to internalize it. I believe you're right that it is the right way to universally serialize command line arguments though. |
So I tried replacing this line: With:
And it was unable to run the commands. Why didn't it work? |
I only took a very brief look at its usage, but isn't the argument to that function already a single serialized command line string (per line 11)?
|
Also, I've never had to actually do this within a script (I've only ever passed command strings to xargs to launch something else), but I think you can convert a command line string to a list using: IFS= read -rd '' -a listname < <(xargs printf '%s\0' <<<"$string") |
Yes regarding line 11, though not always since that function can be called directly as a subcommand. |
So yeah, there's your answer, line 21 should really read:
and then its callers should be passing in lists that have been serialized eg. via The JS analogy for |
So line 87 in herokuish.bash is the one that should be changed, to this:
|
This is one of those holes that can open up if you're not being conscious of how you're outputting your strings. If it could have spaces, quotes, or dollar signs (and you should always treat strings as potentially having these things), and you're putting it somewhere where it will be treated as part of a string representing an argument list (to be deserialized using
xargs -x
, see #17), you should output it withprintf %q
rather than just naively echoing it (which should also be done with printf, see #18).The text was updated successfully, but these errors were encountered: