首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将多个字符串参数用于一个命令

如何将多个字符串参数用于一个命令
EN

Unix & Linux用户
提问于 2019-12-31 03:39:38
回答 2查看 3.8K关注 0票数 2

就像这样:

代码语言:javascript
复制
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

每个参数都是字符串。

EN

回答 2

Unix & Linux用户

发布于 2020-01-28 16:55:25

xargs的输入需要以非常特定的格式格式化。要成为参数的字符串需要用SPC、to、NL (可能还有其他空格字符(取决于xargs实现和区域设置)分隔),如果字符串中可能出现这些字符,则需要用单引号、双引号或反斜杠(只能用反斜杠转义的NL除外)。

反斜杠和引号也需要转义。空元素必须用引号括起来,以免被丢弃。

因此,在这里,您不能使用echoxargs认可的格式输出单词列表。更普遍的情况是,echo不能用于输出任意数据,因为它自己处理反斜杠和/或以-开头的前导参数。

在这里,使用bash,您可以定义:

代码语言:javascript
复制
print-for-xargs() {
  local nl=该函数以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的shell中一样。如果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-client (以及运行bash的参数的bash )的参数中结束--这是错误的做法,因为命令参数在系统上是本地的公共知识(它们显示在ps -f的输出中,并可能以审计日志结尾)。\n'
  if (($# > 0)); then
    set -- "${@//\'/\'\\\'\'}"
    printf "'%s'\n" "${@//$nl/\'\\$nl\'}"
  fi
}

该函数以D8所期望的格式打印其参数(将每个参数放在单引号中,单引号和换行符本身在单引号字符串之外用反斜杠引用)。

然后,你可以:

A9

还请记住,参数展开必须在D10中引用,就像在大多数类似POSIX的shell中一样。

如果D11支持非标准的D12选项(对于输入中以NUL分隔的记录,0是唯一不能在命令参数中出现的字节值),则可以将其大大简化为:

A13

(不需要D14,标准D15也可以)

这是假设您确实出于某种原因需要调用D16,并且您只是展示了一个简化的示例。

在这里,你可以这样做:

A17

而不调用D18或:

A19

而不运行单独的D20解释器实例。

还请注意,在所有这些示例中,D21的值最终都在传递给D22 (以及运行D24的参数的D23 )的参数中结束--这是错误的做法,因为命令参数在系统上是本地的公共知识(它们显示在D25的输出中,并可能以审计日志结尾)。

票数 1
EN

Unix & Linux用户

发布于 2020-07-19 13:12:35

如果允许您使用GNU并行:

代码语言:javascript
复制
echo "$USER $PASSWORD $RESOURCE_MACHINE $SELECT_SQL $TARGET_MACHINE $INSERT_SQL" |
  parallel --colsep ' ' /usr/bin/clickhouse-client -u {1} --password {2} -h {3} -q {4} '|' /usr/bin/clickhouse-client -u {1} --password {2} -h {5} -q {6}

我们假设变量中没有空间。

如果变量中有空格,请选择不出现的字符串(例如:)并使用该字符串:

代码语言:javascript
复制
echo "$USER:::$PASSWORD:::$RESOURCE_MACHINE:::$SELECT_SQL $TARGET_MACHINE:::$INSERT_SQL" |
  parallel --colsep ':::' /usr/bin/clickhouse-client -u {1} --password {2} -h {3} -q {4} '|' /usr/bin/clickhouse-client -u {1} --password {2} -h {5} -q {6}

但是,在特定情况下,这似乎是多余的,因为您可以在命令中直接使用变量。

代码语言:javascript
复制
/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"
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/559632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档