BashとZshでHEREDOCを使用し、パラメータを使用する方法はありますか?

BashとZshでHEREDOCを使用し、パラメータを使用する方法はありますか?

BashとZshのHEREDOCは、次のようなことをしたい場合は、文字列ではなくファイルのように動作するようです。

foo() {
    ruby << 'EOF'
        3.times do
            puts "Ruby is getting the argument #{ARGV[0]}"
        end
EOF 
}

Rubyプログラムにパラメータを渡す方法はありますか?$1Rubyコードに挿入しない方が良いですが、Rubyコードに挿入すると乱雑になる可能性があるため、代わりに'EOF'使用します。EOF

次のようにHEREDOCを文字列として使用する方法があります。

foo() {
    ruby -e "$(cat << 'EOF'
        3.times do
            puts "Ruby is getting the argument #{ARGV[0]}"
        end
EOF
)" $1    
}

そしてそれはうまくいきます(少しハッキングされますが)。しかし、一般的な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を使用できます。

あなたのシステムがまだサポートされていない数少ないシステムの1つであれば、次のことができます。/dev/fd/n

foo() {
  ruby - "$@" << 'EOF'
    3.times do
      puts "Ruby is getting the argument #{ARGV[0]}"
    end
EOF
}

(それ自体は次の意味でruby解釈されます。-標準入力)。

ただし、これはrubyインラインスクリプトの標準入力がheredocになっているため、そのストリームを別の方法で提供しない限り、スクリプトは生の標準入力を介してユーザーにクエリできないことを意味します。

Heredocは、1970年代後半のBourneシェルに付属の機能です。これは0、いくつかのファイル記述子(デフォルトではstdinとも呼ばれます)をいくつかの固定コンテンツにリダイレクトすることを意味するリダイレクト演算子です。 bash5.1+を含むいくつかのシェルは(時々)パイプを使用しますが、もともとこれは一時ファイルを介して実装されました。

また、inはinまたは同様ですが、inとは異なり、オプションの終わりを表示する必要があります。それ以外の場合は、inで始まるオプションとして扱われます。ruby -e code -- arbitrary-argumentsed -e codeperl -e codesh -c codepython -c code--arbitrary-argument-ruby

オプションではない引数 or の後にオプションが必要ないため、または必要ありません。ruby /dev/fd/3 arbitrary-argumentruby - 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'またはawk ''などに似ていますsh -c 'command'。以下はパラメータです。引用符の中にコードを使用して、複数行のテキストを作成できます。 (--たとえば、で始まる次の引数の場合は、オプションの終わりを定義することが重要です。-このトピックも参照してください。回答)

これは本質的にRubyコマンドを囲むシェルラッパーであり、シェルを使用して入力フィルタリング、出力処理、より多くのプログラム呼び出しなどを実行できます。ここパラメータの引用の詳細を見ることができ、シェルスクリプトからRubyコマンドに渡されたすべてのパラメータを引用に置き換えました。などを"$@"使用することもできます。$1$2

もちろん、一重引用符に注意を払う必要があります。可能であれば避けてください。一重引用符で囲まれた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
$ 

関連情報