在不保存文件的情况下执行 ruby 代码

Executing ruby code without saving a file

我想知道如何在不保存文件的情况下执行 ruby 代码。例如:

ruby -e 'Time.now'

但是,引号是个问题,例如:

ruby -e 'puts 'A syntax error''

我可以改用双引号:

ruby -e 'puts "No error"'

或者:

ruby -e "puts 'No error'"

问题是我 运行 容器内的任意代码,所以我无法通过手动替换来避免这个问题,并且转义引号也会产生错误:

ruby -e 'puts \'A syntax error\''

所以我想知道如何在没有文件的情况下执行 ruby 代码,而不用担心代码中的引号。

您必须正确转义引号,例如:

ruby -e 'puts '\''foo bar'\''; puts '\''foo bar'\''; '
#       ^-----^
#      quote this
#                ^-------^
#                quote that
#              ^^
#      escaped quote to pass to Ruby

输出:

foo bar
foo bar

请注意,大多数引号都需要简单地引用 shell 中的 Ruby 代码。转义引号 \' 是传递给 Ruby.

的实际引号

您可以使用 Shell HEREDOC。 shell 之间的确切语法可能不同,但在 BASH 中是:
编辑所有Shell具有相同的语法和相同的行为方式(参见下面的 IEEE 标准引用)。

ruby <<'EOS'
$error = 'A syntax error'
puts $error
EOS

注意<<'EOS'的引号防止Shell在HEREDOC中扩展变量,否则$error 将在传递给 Ruby 之前展开。此外,您可以使用您喜欢的任何 word 而不是 EOS,例如:

ruby <<'end of ruby script'
puts 'example'
end of ruby script

IEEE标准说:

2.7.4 Here-Document

The redirection operators << and <<- both allow redirection of lines contained in a shell input file, known as a "here-document", to the input of a command.

The here-document shall be treated as a single word that begins after the next <newline> and continues until there is a line containing only the delimiter and a <newline>, with no <blank>s in between. Then the next here-document starts, if there is one. The format is as follows:

[n]<<word  
    here-document  
delimiter

where the optional n represents the file descriptor number. If the number is omitted, the here-document refers to standard input (file descriptor 0).

If any character in word is quoted, the delimiter shall be formed by performing quote removal on word, and the here-document lines shall not be expanded. Otherwise, the delimiter shall be the word itself.

If no characters in word are quoted, all lines of the here-document shall be expanded for parameter expansion, command substitution, and arithmetic expansion. In this case, the backslash in the input behaves as the backslash inside double-quotes (see Double-Quotes). However, the double-quote character ( '"' ) shall not be treated specially within a here-document, except when the double-quote appears within $(), ``, or ${}.

If the redirection symbol is <<-, all leading <tab>s shall be stripped from input lines and the line containing the trailing delimiter


更新

也就是说,不可能完全避免冲突。例如,此 Ruby 代码会破坏您的 Shell 脚本:

ruby <<'EOS'
puts <<-EOS
example
EOS
EOS

解决此问题的唯一方法是使用不太可能出现在 Ruby 代码中的 ,例如:

ruby <<'2eGRng8B6NEmNphkA2K4yc9Y782PQZpWzkUW7pwGdmybuMBG5 PVtkzZkeSKGLq4'
puts <<-EOS
example
EOS
2eGRng8B6NEmNphkA2K4yc9Y782PQZpWzkUW7pwGdmybuMBG5 PVtkzZkeSKGLq4

使用Ruby的String Literals

为了避免(或至少简化)在 shell 引号内引用 String 对象的问题,您可以使用 heredoc or a percent-string 例如 %q 用于单引号或 %Q 用于双引号。例如:

# double-quoted percent string
ruby -e 'puts %Q(No error.)'

# single-quoted percent string
ruby -e 'puts %q(A syntax error.)'

# quoted String with nested symbols
ruby -e 'puts %Q[You can use most [percent-literal] symbols safely.]'

请注意,您几乎可以使用任何成对或未成对的符号字符来打开和关闭百分比文字。 ()[]{} 是常见的选择,但是除了单引号和 \' 之外的任何内容都应该在单引号参数中的 shell 之外是安全的至 -e.