複数の文字列引数を1つのコマンドでxargsする方法

複数の文字列引数を1つのコマンドでxargsする方法

このように:

echo $USER $PASSWORD $RESOURCE_MACHINE $SELECT_SQL  $TARGET_MACHINE $INSERT_SQL | xargs -n6 bash -c '/usr/bin/clickhouse-client -u $1 --password $2 -h $3 -q $4 | /usr/bin/clickhouse-client -u $1 --password $2 -h $5 -q $6' bash

各パラメータは文字列です。

ベストアンサー1

xargs'入力は非常に具体的な形式で指定する必要があります。パラメータになる文字列は、xargsSPC、TAB、NL(および実装とロケールによって異なる空白文字)で区切る必要があり、これらの文字が文字列に表示される場合は、単一引用符で囲む必要があります。引用符、二重引用符、またはバックスラッシュ(バックスラッシュでのみエスケープできるNLを除く)。

バックスラッシュと引用符もエスケープする必要があります。そして、空の要素は廃棄されるのを防ぐために引用符で囲む必要があります。

echoしたがって、ここでは認識された形式で単語​​リストを出力することはできませんxargs。より一般的にechoはバックスラッシュおよび/またはで終わるものを処理するため、任意のデータを出力するために使用することはできません-

ここで を使用して、bash以下を定義できます。

print-for-xargs() {
  local nl=$'\n'
  if (($# > 0)); then
    set -- "${@//\'/\'\\\'\'}"
    printf "'%s'\n" "${@//$nl/\'\\$nl\'}"
  fi
}

関数は期待される形式で引数を出力しますxargs(各引数を一重引用符で囲み、一重引用符と改行自体をバックスラッシュとして引用します)。外部一重引用符文字列)。

その後、次のことができます。

print-for-xargs "$USER" \
                "$PASSWORD" \
                "$RESOURCE_MACHINE" \
                "$SELECT_SQL" \
                "$TARGET_MACHINE" \
                "$INSERT_SQL" |
  xargs -n6 bash -c '
    /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$3" -q "$4" |
      /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$5" -q "$6"
    ' bash

また、パラメータ拡張はbash他のほとんどのPOSIX様シェルのように引用する必要があることに注意してください。

xargs非標準オプションをサポートしている場合-0(入力時にNULで区切られたレコードの場合、0はコマンド引数には現れない唯一のバイト値です)、次のように大幅に単純化できます。

print_for_xargs0() {
  [ "$#" -eq 0 ] || printf '%s\0' "$@"
}
print_for_xargs0 "$USER" \
                 "$PASSWORD" \
                 "$RESOURCE_MACHINE" \
                 "$SELECT_SQL" \
                 "$TARGET_MACHINE" \
                 "$INSERT_SQL" |
  xargs -0 -n6 sh -c '
    /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$3" -q "$4" |
      /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$5" -q "$6"
    ' sh

(必要ありませんbash。標準shも大丈夫です)

xargs何らかの理由で実際に電話する必要があり、簡単な例を示しているとします。

ここでは、次のことができます。

  bash -c '
    /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$3" -q "$4" |
      /usr/bin/clickhouse-client -u "$1" --password "$2" -h "$5" -q "$6"
    ' bash "$USER" "$PASSWORD" "$RESOURCE_MACHINE" "$SELECT_SQL" \
           "$TARGET_MACHINE" "$INSERT_SQL"

xargsまったく電話しないでください。

/usr/bin/clickhouse-client -u "$USER" --password "$PASSWORD" \
   -h "$RESOURCE_MACHINE" -q "$SELECT_SQL" |
   /usr/bin/clickhouse-client -u "$USER" --password "$PASSWORD" \
   -h "$TARGET_MACHINE" -q "$INSERT_SQL"

別のインタプリタインスタンスを実行する必要はありませんbash

また、これらすべての例では、 の値は に渡された引数で終わり、次に実行されます。$PASSWORDこれは、コマンド引数がシステムに関する一般的な知識であるため、悪い習慣です(の出力に示されています)。監査ログに残ることがあります)clickhouse-clientbashbashps -f

おすすめ記事