2017-11-26 12 views
1

、のようなカッコでディレクトリ名:私はルビーでsystem呼び出しでそれらを参照すると、私はエスケープする必要がありなぜRubyの `system`は` shellescape`ではないのですか?シェルの中で参照する場合

/tmp/\(example\) 

/tmp/(example) 

は次のようにエスケープする必要がありますそれらが最初の議論であるかどうかに依存して、そうでなくてもよい。

  • 最初の引数としてエスケープされていないディレクトリ。失敗。

    system('/tmp/(example)/script') 
    #>> sh: -c: line 0: syntax error near unexpected token `example' 
    #>> sh: -c: line 0: `/tmp/(example)/script' 
    #=> false 
    
  • 最初の引数としてエスケープされたディレクトリ。成功。

    system('/tmp/(example)/script'.shellescape) 
    #=> true 
    
  • 第2引数としてエスケープされていないディレクトリ。成功。

    system('touch', '/tmp/(example)/script') 
    #=> true 
    
  • 第2引数としてエスケープされたディレクトリ。失敗。

    system('touch', '/tmp/(example)/script'.shellescape) 
    #>> touch: /tmp/\(example\)/script: No such file or directory 
    #=> false 
    

systemは、すべての引数が、コマンド(最初の引数)の名前をエスケープしているようです。

system("#{__dir__}/something") 
  1. なぜsystemがこのように振る舞うん:?それは、コマンドの相対パスを持っているようなスクリプトで問題ですか
  2. すべてをエスケープするネイティブオプションはありますか?

答えて

1

ブラインドで完全なコマンドを#shellescapeで送信することはまれです。

> puts '(pancakes) --house'.shellescape 
\(pancakes\)\ --house 

確かに、カッコをエスケープしたいと思うかもしれませんが、ほとんどの場合、スペースをエスケープしたくありません。正しいこととDWIM(Do What I Mean)を行うために、#systemは、どの部分をエスケープすべきか、どの部分を避けるべきかを推測しなければならず、間違ったことを半分にすることになります。

解決策は決して1つの引数フォーム#systemを使用しないため、シェルをまったく呼び出さないことです。

system('/bin/ls -l') 

この場合、シェルはコマンドラインで起動され、シェルはコマンドを呼び出す前に解析する必要があります。何も心配するエスケープありませんので、

system('/bin/ls', '-l') 

その後、/bin/lsが直接呼び出される

は、何のシェルが関与しない:あなたが言うつもりなら。引数なしシェルなしでコマンドを呼び出す

system('/bin/ls', '--') 
system(['/bin/ls', '--']) 

が、おそらくそれは非常に一般的ではありません、あなたはそれはあなたが扱っているものを知っているときに、手動エスケープ処理に頼ることができます。もちろん、時にはのような愚かなものにつながることと。

外部プログラムと対話する必要がある場合、私は#systemが存在しないと思われがちで、Open3に直接進みます。 Open3は少し冗長ですが、インターフェイスIMOを使いやすく、使いやすくなっています。

コマンドを実行してその出力をキャプチャするためにバッククイックを使用する場合も同様の議論があります。


あなたの第二の例:第二引数の括弧は特別な意味を持っていないので、何のシェルが起動されていないため

# Unescaped directory as second argument. Success. 
> system('touch', '/tmp/(example)/script') 
=> true 

作品。

あなたの第三の例:

# Escaped directory as second argument. Failure. 
> system('touch', '/tmp/(example)/script'.shellescape) 
touch: /tmp/\(example\)/script: No such file or directory 
=> false 

は、同じ理由で失敗した:何のシェルは何のエスケープを意味しません。

+0

"私は'#system'が存在しないと思われがちで、['Open3'](http://ruby-doc.org/stdlib-2.4.2/libdoc/open3/rdoc/Open3 .html)(...) " 'Open3'はこの状況で同じ動作をします。コマンドを実行したいが出力を気にしない場合は 'system'を使い、それ以外の場合は' Open3'を使います。 – user137369

関連する問題