How do I declare a string with both single and double quotes in YAML?
escaping should be done like this
"When you're using double quotes, they look like \"this\""
YAML: Do I need quotes for strings in YAML?
After a brief review of the YAML cookbook cited in the question and some testing, here's my interpretation:
- In general, you don't need quotes.
- Use quotes to force a string, e.g. if your key or value is
10
but you want it to return a String and not a Fixnum, write'10'
or"10"
. - Use quotes if your value includes special characters, (e.g.
:
,{
,}
,[
,]
,,
,&
,*
,#
,?
,|
,-
,<
,>
,=
,!
,%
,@
,\
). - Single quotes let you put almost any character in your string, and won't try to parse escape codes.
'\n'
would be returned as the string\n
. - Double quotes parse escape codes.
"\n"
would be returned as a line feed character. - The exclamation mark introduces a method, e.g.
!ruby/sym
to return a Ruby symbol.
Seems to me that the best approach would be to not use quotes unless you have to, and then to use single quotes unless you specifically want to process escape codes.
Update
"Yes" and "No" should be enclosed in quotes (single or double) or else they will be interpreted as TrueClass and FalseClass values:
en:
yesno:
'yes': 'Yes'
'no': 'No'
yq processing a string with quotation marks
The latest release (v3 onwards) of mikefarah/yq has a --style
option introduced which allows you to do custom formatting of the values. For e.g. you can use --style=double
to double quote the value
yq w -i appconfig.yml config.app.name --style=double exchangedstring
Create a string from characters that contain both single and double quotes?
If you have a version 4.0.0 or later R, you can use r"(all of your text here)"
.
text <- r"(My text "has" double and 'single' quotes)"
> cat(text)
My text "has" double and 'single' quotes
Documentation for this can be found by running help("Quotes")
.
Escape single and double quotes in K8s Lifecycle hook
I'd suggest getting rid of as many layers of quotes as you can. In the original example you have a layer of quotes from YAML, plus a layer of quotes from the sh -c
wrapper. Since you need the HTTP PUT body itself to have both single and double quotes – you need to send the string '"SHUTTING_DOWN"'
with both kinds of quotes over the wire – getting rid of as much quoting as you can is helpful.
In both the shell and YAML, the two kinds of quotes behave differently. Backslash escaping only works in double-quoted strings and so you probably need that at the outer layer; then you need single quotes inside the double quotes; and then you need backslash-escaped double quotes inside that.
In YAML specifically the quotes around strings are usually optional, unless they're required to disambiguate things (forcing 'true'
or '12345'
) to be strings. This lets you get rid of one layer of quoting. You also may find this slightly clearer if you use YAML block style with one list item on a line.
command:
- /bin/sh
- -c
- curl -v -X PUT -d "'\"SHUTTING_DOWN\"'" http://localhost:8080/v1/info/state
I might even go one step further here, though. You're not using environment variable expansion, multiple commands, or anything else that requires a shell. That means you don't need the sh -c
wrapper. If you remove this, then the only layer of quoting you need is YAML quoting; you don't need to worry about embedding a shell-escaped string inside a YAML-quoted string.
You do need to make sure the quotes are handled correctly. If the string begins with a '
or "
then YAML will parse it as a quoted string, and if not then there are no escaping options in an unquoted string. So again you probably need to put the whole thing in a double-quoted string and backslash-escape the double quotes that are part of the value.
Remember that each word needs to go into a separate YAML list item. curl
like many commands will let you combine options and arguments, so you can have -XPUT
as a single argument or -X
and PUT
as two separate arguments, but -X PUT
as a single word will include the space as part of that word and confuse things.
command:
- curl
- -v
- -X
- PUT
- -d
- "'\"SHUTTING_DOWN\"'"
- http://localhost:8080/v1/info/state
Unable to print string containing double quotes in GitLab CI YAML
You could use literal block scalar1 style notation and put the variable definition and subsequent script lines on separate lines2 without worrying about quoting:
myjob:
script:
- |
EXPECT_SERVER_OUTPUT='{"message": "Hello World"}'
or you can escape the nested double quotes:
myjob:
script:
- "EXPECT_SERVER_OUTPUT='{\"message\": \"Hello World\"}'"
but you may also want to just use variables like:
myjob:
variables:
EXPECT_SERVER_OUTPUT: '{"message": "Hello World"}'
script:
- dothething.sh
Note: variables are expanded inside variable definitions so take care with any $
characters inside the variable value (they must be written as $$
to be literal).
1See this answer for an explanation of this and related notation
2See this section of the GitLab docs for more info on multi-line commands
Related Topics
How to Have Rspec Test for My Default Scope
Disable Sprockets Asset Caching in Development
Sinatra Clears Session on Post
In Ruby, Can You Perform String Interpolation on Data Read from a File
What Does "||=" Do in Ruby 1.9.2
Interpretation as a Local Variable Overrides Method Name
Error Installing Ruby with Rvm (Osx 10.8)
How to Elegantly Rename All Keys in a Hash in Ruby
Best Way to Pretty Print a Hash
How to Create a Nokogiri Case Insensitive Xpath Selector
Invalid Gemspec -Illformed Requirement ["#<Yaml::Syck::Defaultkey:0Xb5F9C990> 3.2.0"]
Getting Openssl::X509::Certificateerror Nested Asn1 Error on Ruby
Building Ruby with Rbenv and Ruby-Build Fails with Undefined Symbol: Sslv2_Method
Selenium-Webdriver Ruby --> How to Wait for Images to Be Fully Loaded After Click