이와 같이:
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
' 입력은 매우 구체적인 형식으로 지정되어야 합니다. 매개변수가 될 문자열은 xargs
SPC, 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-client
bash
bash
ps -f
답변2
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"