【发布时间】:2018-04-06 15:31:15
【问题描述】:
我使用 HPC 集群。计算节点不能上网,只有前端。
所以我想包装所有需要访问互联网的命令,以便在正面执行它们。
例如:对于 wget
#!/bin/bash
ssh frontal /bin/wget "$@"
-> 工作正常
我必须包装这个 bq (google BigQuery) 命令:
bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sensing_time LIKE '2016%' AND mgrs_tile == '32ULU' ORDER BY sensing_time ASC LIMIT 1000;"
我设法重新引用命令并在 CLI 上成功启动它:
ssh frontal '~/downloads_and_builds/builds/google-cloud-sdk/bin/bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sensing_time LIKE '"'"'2016%'"'"' AND mgrs_tile == '"'"'32ULU'"'"' ORDER BY sensing_time ASC LIMIT 1000;"'
现在我想编写一个名为 bq 的包装器,它能够获取参数并通过 ssh 启动此命令......这是我尝试过的:
#!/bin/bash
set -eu
# all parameters in an array
args=("$@")
# unset globing (there's a * in the SELECT clause)
set -f
# managing inner quotes
arg2=`echo "${args[2]}" | perl -pe 's/'\''/'\''"'\''"'\''/g'`
# put back double quotes (") suppressed by bash
args="${args[0]} ${args[1]} \"${arg2}\""
# build command with parameters
cmd="~/downloads_and_builds/builds/google-cloud-sdk/bin/bq $args"
echo ""
echo "command without external quotes"
echo "$cmd"
echo ""
echo "testing it ..."
ssh hpc-login1 "$cmd"
echo ""
# wrapping command between simple quotes (like on the CLI)
cmd="'"'~/downloads_and_builds/builds/google-cloud-sdk/bin/bq '"$args""'"
echo "commande with external quotes"
echo "$cmd"
echo ""
echo "testing it ..."
ssh hpc-login1 $cmd
echo "done"
这是该脚本的输出: $ bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sense_time LIKE '2016%' AND mgrs_tile == '32ULU' ORDER BY sense_time ASC LIMIT 1000;"
command without external quotes
~/downloads_and_builds/builds/google-cloud-sdk/bin/bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sensing_time LIKE '"'"'2016%'"'"' AND mgrs_tile == '"'"'32ULU'"'"' ORDER BY sensing_time ASC LIMIT 1000;"
testing it ...
Waiting on bqjob_r102b0c22cdd77c2d_000001629b8391a3_1 ... (0s) Current status: DONE
commande with external quotes
'~/downloads_and_builds/builds/google-cloud-sdk/bin/bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sensing_time LIKE '"'"'2016%'"'"' AND mgrs_tile == '"'"'32ULU'"'"' ORDER BY sensing_time ASC LIMIT 1000;"'
testing it ...
bash: ~/downloads_and_builds/builds/google-cloud-sdk/bin/bq --format=json query "SELECT * FROM [bigquery-public-data:cloud_storage_geo_index.sentinel_2_index] WHERE sensing_time LIKE '2016%' AND mgrs_tile == '32ULU' ORDER BY sensing_time ASC LIMIT 1000;": Aucun fichier ou dossier de ce type (in english: no file or directory of this kind)
如您所见,我设法获得了正确的命令字符串,就像在 CLI 上运行的那样,但它在我的脚本中不起作用:
- 第一次尝试成功但没有输出(我已尝试将其重定向到文件中:文件已创建但为空)
- 在第二次尝试中(使用外部简单引号,就像 CLI 命令一样),bash 将带引号的 arg 作为一个块,但找不到命令...
有人知道如何使用包装脚本通过 ssh 启动复杂的命令(带引号、通配符...)吗?
(即。一个名为 foo 的包装器能够替换 foo 命令并使用提供的参数通过 ssh 正确执行它)
【问题讨论】:
-
从文件中读取查询不是一个选项吗?
bq query < query_text.sql。最好不要乱跑。
标签: bash ssh google-bigquery double-quotes single-quotes