如何在Bash脚本中通过psql判断PostgreSQL角色是否存在?
判断PostgreSQL指定角色是否存在的Bash脚本实现
我需要在Bash脚本中添加一个IF条件,用于判断PostgreSQL数据库中是否存在指定角色。已找到SQL代码层面的解决方案,但需要能直接在Bash中使用的实现方式,预计借助psql工具完成。参考资料中也有psql相关方案,但无法将其适配到IF语句中。
作为PostgreSQL和Bash新手,我尝试了以下代码但未成功:
psql_USER=my if [ "$( psql -h db -U postgres --no-psqlrc --single-transaction --pset=pager=off --tuples-only --set=ON_ERROR_STOP=1 -tc "SELECT 1 FROM pg_user WHERE usename = $psql_USER" | grep -q 1 )" == '1' ] > /dev/null 2> /dev/null; then echo "HOURRA !" fi;
执行结果如下:
Password for user postgres: ERROR: column « my » does not exist LINE 1: SELECT 1 FROM pg_user WHERE usename = my ^
问题分析
- SQL语法错误:直接在SQL语句中使用
$psql_USER,PostgreSQL会把my解析成列名而非字符串值,导致报错。 grep -q使用错误:grep -q是静默匹配模式,它的返回值是退出状态码(0表示找到匹配,1表示未找到),不会输出任何内容,因此无法通过捕获它的输出来和'1'比较。
正确实现方式
方式一:利用命令退出状态判断
直接将grep -q作为if条件的判断依据,它的退出状态码会被if自动识别:
psql_USER="my" if psql -h db -U postgres --no-psqlrc --single-transaction --pset=pager=off --tuples-only --set=ON_ERROR_STOP=1 -tc "SELECT 1 FROM pg_user WHERE usename = '$psql_USER'" | grep -q 1; then echo "HOURRA !" fi
方式二:捕获输出内容判断
先获取psql的查询结果,清理掉多余空格后再进行判断:
psql_USER="my" # 去掉输出中的空格、换行等空白字符 result=$(psql -h db -U postgres --no-psqlrc --single-transaction --pset=pager=off --tuples-only --set=ON_ERROR_STOP=1 -tc "SELECT 1 FROM pg_user WHERE usename = '$psql_USER'" | tr -d '[:space:]') if [ "$result" = "1" ]; then echo "HOURRA !" fi
进阶优化:安全处理特殊字符
如果用户名可能包含单引号等特殊字符,直接拼接SQL会有语法错误甚至注入风险,建议使用psql的内置变量替换功能:
psql_USER="my" result=$(psql -h db -U postgres --no-psqlrc --single-transaction --pset=pager=off --tuples-only --set=ON_ERROR_STOP=1 --set=target_user="$psql_USER" -tc "SELECT 1 FROM pg_user WHERE usename = :target_user" | tr -d '[:space:]') if [ "$result" = "1" ]; then echo "HOURRA !" fi
额外提示
为了避免脚本运行时手动输入密码,可以:
- 设置
PGPASSWORD环境变量:export PGPASSWORD="你的密码" - 配置
~/.pgpass文件(权限需设为600),格式为:主机:端口:数据库:用户名:密码
内容的提问来源于stack exchange,提问作者lalebarde
相关产品推荐
相关产品推荐

