就像这样:
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每个参数都是字符串。
发布于 2020-01-28 16:55:25
xargs的输入需要以非常特定的格式格式化。要成为参数的字符串需要用SPC、to、NL (可能还有其他空格字符(取决于xargs实现和区域设置)分隔),如果字符串中可能出现这些字符,则需要用单引号、双引号或反斜杠(只能用反斜杠转义的NL除外)。
反斜杠和引号也需要转义。空元素必须用引号括起来,以免被丢弃。
因此,在这里,您不能使用echo以xargs认可的格式输出单词列表。更普遍的情况是,echo不能用于输出任意数据,因为它自己处理反斜杠和/或以-开头的前导参数。
在这里,使用bash,您可以定义:
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的输出中,并可能以审计日志结尾)。
发布于 2020-07-19 13:12:35
如果允许您使用GNU并行:
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}我们假设变量中没有空间。
如果变量中有空格,请选择不出现的字符串(例如:)并使用该字符串:
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}但是,在特定情况下,这似乎是多余的,因为您可以在命令中直接使用变量。
/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"https://unix.stackexchange.com/questions/559632
复制相似问题