63607
curl のパラメータを少しだけ変えたリクエストを何度も送りたいので  
共通のコマンド文字列を定義して変更する部分だけ文字列を連結して実行したいです

具体的には

```

    curl https://xxxxx
    -d 'abc=xxxxxxxx'
    -d 'def=xxxxxxxx'
    -d 'ghi=xxxxxxxx'
    -d 'jkl=xxxxxxxx'
      :
    
```

と言う20個ぐらいのパラメータの後

```

    -d 'xyz=xxxxxxx'
    
```

と言うパラメータだけ変更して curl を叩くと言うスクリプトを書きたいです

なので前半部分を文字列変数(例えば$COMMAND)で定義しておいて

```

    $COMMAND -d 'xyz=xxxxxxx'
    $COMMAND -d 'xyz=yyyyyyy'
    $COMMAND -d 'xyz=zzzzzzz'
    
```

みたいにかけるとスクリプトが見やすくなるかなと思っています

ただ前半のコマンドパラメータが量が多いのでできれば１行ずつ別の行に書きたくて  
パラメータの中に ' も " も使ってたりしてエスケープが大変なので  
ヒアドキュメントを使ってかけるといいかなと思っています

そこで以下のような ls と -l を別の行に書いて後から引数を追加して実行するような  
テストコードを書いてみたんですがうまく行きません

```

    COMMAND=<<EOS
    ls \
    -l
    EOS
    
    echo $COMMAND # デバッグ用　何も出力されない
    $($COMMAND ~) # ls -l ~ が実行されて欲しい
    
```

ヒアドキュメントなしで

```

    COMMAND='ls -l'
    echo $COMMAND # ls -l が表示される
    $($COMMAND ~)
    
```

と書いてみても

```

    ls -l
    test.sh: line 3: total: command not found
    
```

となってしまいます

どうすればやりたいことができるでしょうか
CC BY-SA 4.0
2020-03-05T10:24:34.497
63602
2020-03-06T23:26:58.400
2020-03-06T05:28:04.477
question
bash
ヒアドキュメントで指定した改行を含むコマンド文字列を実行したい
bash のヒアドキュメントは文字列リテラルではなく標準入力として扱われます。  
そのため記載されたソースでは 変数 COMMAND に格納しているつもりかと思いますが COMMAND には何も格納されません。

エスケープが大変さがどの程度のものかわかりませんが、共通処理化したいのであればふつうに関数化するのはいかがでしょうか？

```

    myls()
    {
        ls \
         -l \
          "$@" ;
    }
    
    myls ~ 
    myls /
    
```
CC BY-SA 4.0
2020-03-05T11:19:26.260
63607
2020-03-06T04:25:14.020
2020-03-06T04:25:14.020
3061
27410
63602
answer
KTIさんが本来行いたいことは、

連続した引数リストの中からn個の引数を取り、それをパラメーターとしてコマンドを実行するを引数÷n回繰り返したい。

ということではないでしょうか？

であれば、ヒアドキュメントを使わずに

```

    #!/bin/sh
    
    while [ -n "$1" ]
    do
        arg1=$1
        shift
        echo "count" \
        $arg1
    done
    
```

結果

> count 1  
>  count 2  
>  count 3  
>  count 4  
>  count 5  
>  count 6

一回のコマンド実行に必要な可変パラメーターが複数個の場合は

```

    #!/bin/sh
    
    while [ -n "$1" ]
    do
        arg1=$1
        shift
        arg2=$1
        shift
        echo $arg1 \
        $arg2
    done
    
```

結果

> 1 2  
>  3 4  
>  5 6

という方法もあると思います。

```

    arg1=$1
    shift
    
```

がキモで、これで、現在の引数の最初の一個を変数に保存し、引数リストからその一個を取り除きます（前に詰まる）

これにより、引数の先頭を望む意味の変数に代入し、引数リストから取り除くことを繰り返し、必要個数のコマンドに渡す引数を変数に代入し終えたらコマンドを実行し、引数がまだ残っている（処理したい対象がまだある）か？を判定する`while`で繰り返し実行します。

期待した回答でない場合には申し訳ありません
CC BY-SA 4.0
2020-03-05T11:20:43.320
63608
2020-03-05T11:20:43.320
14745
63602
answer
質問に対する直接の回答です。

【ヒアドキュメントの記述例その１】

```

    COMMAND=$(cat <<EOS
    ls \
    -l
    EOS
    )
    
```

【ヒアドキュメントの記述例その２】  
`Bourne Shell`でも使える方法です。

```

    COMMAND=`cat <<EOS
    ls \
    -l
    EOS
    `
    
```

【オプションを細かく分ける方法】  
ヒアドキュメントを使わずにオプションを細かく分けてもよいと思います。

```

    OPT_A="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
    XXX="XXXXXXXXXXXXXXXXX"
    YYY="YYYYYYYYYYYYYYYYY"
    OPT_B="BBBBBBBBBBBBBBBBB ${XXX} ${YYY} BBBBBBBBBBBBBBBBBBBBBBBBBB"
    OPT_C="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
    
    OPTS="${OPT_A} ${OPT_B} ${OPT_C}"
    COMMAND="echo"
    ${COMMAND} ${OPTS}
    
```

* * *

* * *

質問に追記された具体例の実装です。curlはダミーです。

【コード】

```

    #!/bin/bash
    curl(){ #dummy
        echo ${FUNCNAME[0]} $@
        return 0
    }
    
    xcurl(){
        arg=$1
        p=""
        p=${p}" ""-d 'abc=xxxxxxxx'"
        p=${p}" ""-d 'def=xxxxxxxx'"
        p=${p}" ""-d 'ghi=xxxxxxxx'"
        p=${p}" ""-d 'jkl=xxxxxxxx'"
        p=${p}" ""..."
        p=${p}" ""${arg}"
    
        curl ${p}
    
        return 0
    }
    xcurl "-d 'xyz=xxxxxxxx'"
    
```

【実行結果】

```

    curl -d 'abc=xxxxxxxx' -d 'def=xxxxxxxx' -d 'ghi=xxxxxxxx' -d 'jkl=xxxxxxxx' ... -d 'xyz=xxxxxxxx'
    
```
CC BY-SA 4.0
2020-03-05T11:57:02.507
63609
2020-03-06T23:26:58.400
2020-03-06T23:26:58.400
35558
35558
63602
answer
別の方の回答のように関数化するか、配列変数を用いましょう。コマンドラインの引数を含めた文字列を含む変数の展開は、変数展開後に行なれるワード分割とパス名展開がどう適用されるか理解していないと危険です。

配列変数の例を紹介します。

```

    #!/bin/bash
    
    ls_custom=(ls -l -d)
    "${ls_custom[@]}" ~
    "${ls_custom[@]}" /etc /var
    
```

参考までに、「変数に入れる文字列を複数行で記述したいが使用(変数展開)するときに改行は不要」という要件を満たす書き方もどうぞ。

```

    #!/bin/bash
    COMMAND="\
    ls \
    -l
    "
    
    $COMMAND ~
    
```
CC BY-SA 4.0
2020-03-06T04:33:54.767
63619
2020-03-06T04:46:19.443
2020-03-06T04:46:19.443
3061
3061
63602
answer