bash
  • shell
  • unix
  • quotes
  • 2012-02-28 21 views 10 likes 
    10

    私は、複数の引用符で囲まれた単語を含む文字列変数を、コマンドのパラメータとして置き換えようとしています。引用符で囲まれた複数単語の文字列を引数に代える方法は?

    したがって、私たちを与える次のサンプルスクリプト(出力が標準エラーに記録させるシェバングに-xを、注)、

    #!/bin/bash -x 
    
    myArg="\"hello\" \"world\"" 
    echo "string is:" $myArg 
    
    exit 
    

    を与え、

    + myArg='"hello" "world"' 
    + echo 'string is:' '"hello"' '"world"' 
    string is: "hello" "world" 
    + exit 
    


    2行目は実際にコマンドに渡される内容を示しています。 bashは、文字列の各単語に一重引用符を追加しました。代わりに、私が代わりに "$ myArg"を引用すると、同じことが起こりますが、各単語ではなく文字列全体で発生します。

    echoの代わりに、"*"(シェルで展開してはならない)のように、引数の一部を引用符で囲む必要があるプログラムに文字列を渡しているとします。

    明確にするために、私は展開中に一重引用符を追加したくありません。どうすればこれを達成できますか?

    +0

    何をしていますか?'eval'を使ってプログラムに渡された文字列に' '* ''や '*'が含まれているかどうかは関係ありません。 – Sorpigal

    +0

    混乱している人には:シバンの '-x'に注意してください。すると出力がログに記録されます。 – user123444555621

    +0

    @ Pumbaa80、確かに、私は質問にその明確化を加えました。 –

    答えて

    13

    は、配列を使用し、引用符を使用しないでください(BashFAQ #050を参照してください):

    $ myArgs=("hello" "world" "multiword arg with * ?") 
    + myArgs=("hello" "world" "multiword arg with * ?") 
    $ echo "${myArgs[@]}" 
    + echo hello world 'multiword arg with * ?' 
    hello world multiword arg with * ? 
    

    実際に文字列内で引用符で囲まれた文字列の形にする必要がある場合は、eval "echo $myArg"のようなものを使用するか(注意しないと本当に厄介なバグを引き起こす可能性があります)それは困難になるだろう)。

    +0

    この配列アプローチは完璧に動作します、ありがとう! ps。サブシェルからのすべての印刷命令は親のシェルによって解釈されるので、そのような 'eval'ステートメントは同じ種類の悪い結果を与えていたようです。 –

    4

    あなたは、パラメータ(SO上の例、99%)として、変数の値を渡したい場合は、単に適切なquotingを使用します。

    arg="foo bar" 
    command "$arg" 
    

    あなたはいくつかの引数、使用アレイ渡す場合:

    は、
    args=("foo bar" "baz ban" bay) 
    command "${args[@]}" 
    
    +0

    @ gordon-davisson、配列は確かに答え、多くのありがとう! –

    0

    あなたがしていると思っているとは思わない。

    [~]$ myArg="\"hello\" \"world\"" 
    [~]$ echo "string is:" $myArg 
    string is: "hello" "world" 
    

    私はどんなkind- echoの余分な引用符が3つの引数文字列を取得していない参照してください。

    [~]$ cargs(){ echo $#; } 
    [~]$ cargs "string is:" $myArg 
    3 
    

    バッシュは、最初の変数を展開します(文字列エスケープがピタ理由リテラルbackslashes-このなしであるが)ので

    cargs "string is:" $myArg 
    

    となる

    cargs "string is:" "\"hello\"" "\"world\"" 
    

    とargs配列は:

    0x00:string is:0 
    0x0B:"hello"0 
    0x13:"world"0 
    0x1B:0 
    

    *を追加するか、それらのいずれかにglobパス展開を追加すると、エスケープしないか、リテラルコマンドでシングルクォートを使用しない限り、Bashはこの時点で展開します。

    [~]$ cargs "string is:" $myArg * 
    19 
    [~]$ cargs "string is:" $myArg "\*" 
    4 
    [~]$ cargs "string is:" $myArg '*' 
    4 
    
    +0

    Echoの* output *は、引用された単語を完全に表示しますが、エコーに渡される入力引数(質問のデバッグ出力の2行目のように)は一重引用符で囲まれた二重引用符( '"str"')私が使用しているツールの無意味な入力です。 –

    関連する問題