non*_*ity 6 bash zsh shell-script here-document
Bash 和 Zsh 的 HEREDOC 似乎像一个文件,而不是字符串,如果我希望做类似的事情
foo() {
ruby << 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将参数传递给 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
}
Run Code Online (Sandbox Code Playgroud)
它有效(虽然有点hacky)。但是有没有一种方法可以使用HEREDOC 的通常方式将其视为文件并能够向Ruby 提供参数?
Sté*_*las 10
在带有 的系统上,您始终可以执行以下操作:/dev/fd/n
foo() {
ruby /dev/fd/3 "$@" 3<< 'EOF'
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
EOF
}
Run Code Online (Sandbox Code Playgroud)
这里使用 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
}
Run Code Online (Sandbox Code Playgroud)
(其中ruby本身解释-为含义stdin)。
但这意味着ruby内联脚本的标准输入现在是heredoc,因此除非您以其他方式提供该流,否则该脚本将无法通过原始标准输入查询用户。
Heredoc 是 70 年代后期 Bourne shell 附带的一项功能。这是一个重定向操作符,它的意思是将一些文件描述符(0默认情况下也称为 stdin)重定向到一些固定内容。最初,这是通过临时文件实现的,尽管包括 bash5.1+ 在内的一些 shell 使用(有时)管道代替。
另请注意,与 in或in一样,但与 in 不同的是,您确实需要将其标记为选项的结尾,否则,如果以开头,则将其视为 to 的选项。ruby -e code -- arbitrary-argumentsed -e codeperl -e codesh -c codepython -c code--arbitrary-argument-ruby
我们并不需要它,也不是没有预期非选项参数是经过选择或。ruby /dev/fd/3 arbitrary-argumentruby - arbitrary-argument-/dev/fd/3
您可能想使用这种语法,只需将 ruby 程序包含在单引号中:
#!/bin/sh -
foo() {
ruby -e '
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
' -- "$@"
}
foo test-arg
Run Code Online (Sandbox Code Playgroud)
类似于python -c 'command'orawk ''或sh -c 'command'etc. 后跟参数。在引号内,您可以使用代码编写多行文本。(--对于定义选项的结尾很重要,例如对于以下参数以 开头的情况-,另请参阅此答案)
这实际上是 ruby 命令的外壳包装器,您可以使用外壳过滤输入、处理输出、调用更多程序等。此外,在这里您可以看到更多关于引用参数的信息,我已替换"$@"为引用所有参数,从shell脚本传递到ruby命令,你也可以使用$1,$2等等
当然,单引号需要一些注意。如果可以,请避免它们。使用它们的方法可能不止一种,例如\047或\'在两个单引号字符串之间插入。例子:
#!/bin/sh -
foo() {
ruby -e '
3.times do
puts "Ruby is getting the argument #{ARGV[0]}"
end
' -- "$@"
}
foo test-arg
Run Code Online (Sandbox Code Playgroud)
这里有更多关于引用的内容。