Bash 和 Zsh 的 HEREDOC 似乎就像一个文件,而不是字符串,如果我希望做类似的事情
foo() {
ruby << 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
有没有办法将参数传递给 Ruby 程序?最好不要将 插入$1
到 Ruby 代码中,这就是我使用'EOF'
而不是 的原因EOF
,因为插入到 Ruby 代码中可能会很混乱。
有一种方法可以将 HEREDOC 作为字符串使用,方法如下:
foo() {
ruby -e "$(cat << 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
)" $1
}
并且它有效(虽然有点hacky)。但是有没有办法使用 HEREDOC 通常的方式将其视为文件并能够向 Ruby 提供参数?
答案1
在带有 的系统上,您始终可以执行以下操作:/dev/fd/n
foo() {
ruby /dev/fd/3 "$@" 3<< 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
这里使用高于 2 的 fd,因此您的ruby
脚本仍然可以使用 stdin/stdout/stderr 而不受影响。
如果您的系统是少数仍然不支持的系统之一,您可以执行以下操作:/dev/fd/n
foo() {
ruby - "$@" << 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
(ruby
其本身解释-
为含义标准输入)。
但这意味着ruby
内联脚本的标准输入现在是heredoc,因此该脚本将无法通过原始标准输入查询用户,除非您以其他方式提供该流。
Heredoc 是 70 年代末随 Bourne shell 附带的一项功能。它是一个重定向运算符,意味着将某些文件描述符(0
默认情况下又称为 stdin)重定向到某些固定内容。最初,这是通过临时文件实现的,尽管一些 shell,包括 bash5.1+ 使用(有时)管道。
另请注意, in 与 in或类似,但与 in , 不同,您确实需要标记选项的结尾,否则如果以 开头,它将被视为 的选项。ruby -e code -- arbitrary-argument
sed -e code
perl -e code
sh -c code
python -c code
--
arbitrary-argument
-
ruby
我们不需要它在nor中,因为在非选项参数or之后不需要选项。ruby /dev/fd/3 arbitrary-argument
ruby - arbitrary-argument
-
/dev/fd/3
答案2
您可能想使用此语法,只需将 ruby 程序包含在单引号中即可:
#!/bin/sh -
foo() {
ruby -e '
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
' -- "$@"
}
foo test-arg
类似于python -c 'command'
or awk ''
orsh -c 'command'
等。后面是参数。在引号内,您可以使用代码编写多行文本。 (--
定义选项的结尾很重要,例如对于以下参数以 开头的情况-
,另请参阅此回答)
这实际上是 ruby 命令的 shell 包装器,您可以使用 shell 来过滤输入、处理输出、调用更多程序等。这里您可以看到有关引用参数的更多信息,我已替换为 来"$@"
引用所有参数,从 shell 脚本传递到 ruby 命令,您也可以使用等$1
。$2
当然,需要注意单引号。如果可以的话,请避开它们。使用它们的方法可能不止一种,例如在两个单引号字符串之间\047
插入或插入。\'
例子:
$ ruby -e 'puts "Ruby\047s #{ARGV[0]}"' great
Ruby's great
$ ruby -e 'puts "Ruby'\''s #{ARGV[0]}"' great
Ruby's great
这里更多关于引用的内容。
答案3
参数“-”表示“标准输入”。
foo() {
ruby - "$@" << 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
$ foo bar
Ruby is getting the argument bar
Ruby is getting the argument bar
Ruby is getting the argument bar
$