Postgresql

在 unix 中將變數與 0 進行比較時獲取錯誤的結果

  • October 29, 2019

我在unix中有以下程式碼

#!/bin/bash
user=$1
username=$user'%'
DB_name=$2
userpwd=$4
export PGPASSWORD=$3

psql -h localhost -U postgres -d $DB_name -At -c "SELECT COUNT(*) AS USER_COUNT FROM pg_roles WHERE rolname = '${user}' " \
| while read -a Record ; 
do
USER_COUNT=${Record[0]} 
echo 'user USER_COUNT ' $USER_COUNT
done

echo 'count' $count
if   [[ $(($USER_COUNT)) -eq 0 ]]
then
echo 'New User ' $user
else
echo 'User Exists ' $user

fi

它基本上接受給定的使用者名並檢查它是否存在於 Postgresql 中。在我們傳遞參數之後,它會檢查它的計數,如果使用者名存在則為 1,否則為 0,並將其儲存在變數中USER_COUNT。然後它將它與 0 進行比較。但比較結果是錯誤的。不管使用者名是否存在,它只執行 if 的“真”部分。

Edit-1正如 Phill 所建議的那樣,我使用if [[ $(($USER_COUNT)) -eq 0 ]]而不是 的 原因if [$USER_COUNT -eq 0 ]是因為我收到了一條錯誤消息,否則會說一元運算符是預期的。我在某處讀到這是因為它$USER_COUNT是一個未設置的變數。

Edit-2感謝您的建議 Lennart。按照他的建議,我添加-x到我的第一行,發現即使$USER_COUNT使用者存在時的值為 1,否則為 0,但是在比較時,即在 step if [[ $(($USER_COUNT)) -eq 0 ]]中,$USER_COUNT取值為 0,即使之前它是 1 . 因此,它總是評估為真。但我不確定如何解決上述情況。

Edit-3非常感謝 Lennart。你的程式碼解決了我的問題。

你可以考慮這樣的事情:

#!/bin/bash
...
cnt=$(psql -h localhost -U postgres -d $DB_name -At -c "SELECT COUNT(*) AS USER_COUNT FROM pg_roles WHERE rolname = '${user}' ")

if [[ ${cnt} -eq 0 ]]
then
   echo 'New User ' $user
else
   echo 'User Exists ' $user
fi

您說一元運算符預期的錯誤確實是因為變數未設置。有多種處理方法,但在這種情況下,我認為應該沒問題

如果

$$ [ $(($USER_COUNT)) -eq 0 $$]

鑑於這是 bash 並且您只是在執行一個簡單的數字比較,那麼“if”條件不應該看起來更像這樣嗎?

if [ $USER_COUNT -eq 0 ] 

雙方括號做一些“更多”的事情,允許使用正則表達式和其他你不需要的怪異。

就個人而言,我不會依靠計數來檢測任何東西。從記錄中檢索一些確定的東西(比如名字)並確保你得到了一些東西——你可能會因為任何原因得到一個零計數。

另外,請閱讀使用 Postgres 密碼文件將密碼輸入 psql。 https://www.postgresql.org/docs/9.1/libpq-pgpass.html

引用自:https://dba.stackexchange.com/questions/252124