我有一个别名,它是数据库的 psql 连接字符串,假设别名是这样的:
alias GQQ='psql "host=$host user=$redshift_uname dbname=$redshift_dbname port=$port pass word=$redshift_pwd"'
这个别名的存在是为了让我可以连接到数据库,但我也想在函数中调用它来向数据库发送简单的查询。
在常规终端中,我可以运行 First: GQQ <<EOF
Second:<QUERY> ex. SELECT * FROM table LIMIT 10;
和 Third: EOF
,我的查询将返回结果。
我想创建模拟此功能的函数,如下所示:
function qredshift() {
GQQ <<EOF
$*
EOF
}
但我不确定如何制定这个,我已经在 shell 中尝试过 shell 并在不同的地方添加引号,运行这个的正确方法是什么?
答案1
您需要 是EOF
该行的完整内容才能将其视为分隔符。
qredshift() {
local IFS=' '
psql "host=$host user=$redshift_uname dbname=$redshift_dbname port=$port password=$redshift_pwd" <<EOF
$*
EOF
}
当在此处文档中找到 $* 时,位置参数将与第一个字符$IFS
或空格连接,具体取决于 shell。因此,我们设置IFS
空间以使 shell 之间的行为保持一致。在 中zsh
,您还可以使用${(j[ ])@}
显式连接空格。
除了此处的文档,您还可以使用:
printf '%s\n' "$*" | psql...
或者:
printf '%s\n' "$@" | psql...
将 的每个参数qreshift
作为单独的输入行传递给psql
。
或者使用 zsh 风格的here-strings(现在 bash 和其他一些 shell 也支持):
psql... <<< "$*"
psql
(假设这是 postgresql 客户端)也可以使用 SQL 查询来执行-c
,所以:
psql -c "$*" ...
如果没有提供参数,要从qredshift
参数或 stdin 获取 SQL 代码,您可以这样做:
qredshift() {
local IFS=' '
psql ${1+"-c$*"} "host=$host user=$redshift_uname dbname=$redshift_dbname port=$port password=$redshift_pwd"
}
然后你可以这样做:
qredshift 'select * from...'
qredshift <<< 'select * from...'
qredshift << 'EOF'
select * from...
EOF
请注意,在命令行上传递密码是不好的做法,因为这是系统内的公共信息。
通过环境变量而不是在参数中传递PGPASSWORD="$redshift_pwd" psql ...
密码更安全,因为环境变量是私有的。