簡體   English   中英

bash腳本不使用作為變量傳遞的值執行mysql命令

[英]bash script not executing mysql command with values passed as variables

我正在修改一組處理視頻文件並將處理步驟報告給 mysql 數據庫的 bash 腳本(這是有問題的原始代碼)。

執行數據庫報告的函數是從主處理腳本中調用的,在原始腳本中如下所示:

_report_to_db(){
if [ "${REPORT_TO_DB}" = "Y" ] ; then
    echo "INSERT IGNORE INTO tableA (objectIdentifierValue,object_LastTouched) VALUES ('${MEDIA_ID}',NOW()) ON DUPLICATE KEY UPDATE object_LastTouched = NOW()" | mysql --login-path="${LOGIN_PROFILE}"  "${DB_NAME}" 2> /dev/null
    _db_error_check
fi
}

由於腳本旨在直接從命令行運行,因此當您以這種方式運行它們時,它可以正常工作。 但是我正在通過 php 從 Web 界面運行它們,並且在引用/轉義空格和/或變量時有一些惡作劇。

例如,腳本在...| mysql之后的空格處中斷...| mysql ...| mysql並且它認為我試圖在沒有密碼的情況下以 root 身份運行 mysql 並完全忽略--login-path和我正在向它傳遞的其他內容。

當我從這樣的變量調用mysql

_report_to_db(){
    if [ "${REPORT_TO_DB}" = "Y" ] ; then

        SQL_ARRAY=(INSERT IGNORE INTO tableA (columnA,lastTouched) VALUES ("${SOME_PASSED_VALUE}",NOW()) ON DUPLICATE KEY UPDATE object_LastTouched = NOW();)
        MYSQL_COMMAND_ARRAY=(mysql --login-path="${LOGIN_PROFILE}" -e "${SQL_ARRAY[@]}" "${DB_NAME}")

        echo "$(${MYSQL_COMMAND_ARRAY[@]})"

        _db_error_check

    fi
}

...我能夠正確登錄到 mysql,但 SQL 查詢被忽略(當它echo是結果時,您將獲得標准的 MySQL --help輸出。

到目前為止,我已經嘗試了各種引用、轉義、將查詢作為單獨的字符串變量引用、作為數組(如您所見)的各種變體。

同樣沒有幫助的是原始_db_error_check()函數只檢查管道退出狀態的值。 因此,如果管道沒問題,但在路徑更遠的地方出現問題,它會默默地失敗。

_db_error_check(){
    if [ "$?" != "0" ] ; then
    # reports an error if the pipe exit value ≠ 0
    else 
    # everything is ok! even if there was a mysql error
    fi
}

這不是文件或數據庫權限問題(已經三重檢查了)。 有沒有我遺漏的引號或其他一些愚蠢的東西? 謝謝! 哦,我正在運行 OSX El Capitan。

更新

大聲笑,我打算發布調用腳本的 PHP,然后我想起 PHP 實際上正在調用一個 Pyhton 腳本,它也執行一些其他處理,就是調用 bash 腳本的原因。 一切都在這里:

PHP

$command = escapeshellcmd("/usr/local/bin/python3 /Users/user/path/to/ingest.py " . $user . " 2>&1");

while (@ ob_end_flush());
$proc = popen($command, 'r');
echo '<pre>';
while (!feof($proc))
{
    echo fread($proc, 4096);
    @ flush();
}
echo '</pre>';

PYTHON

for item in os.listdir(ingestDir):
    if not item.startswith("."):
        filePath = os.path.abspath(ingestDir+"/"+item)
        fileNameForMediaID = os.path.splitext(item)[0]
        try:
            ingest = subprocess.Popen(['/usr/local/bin/ingestfile','-e','-u',user,'-I',filePath,'-m',fileNameForMediaID])
            ingest.wait()
            os.remove(filePath)
        except IOError as err:
            print("OS error: {0}".format(err))

更新 2

我認為這實際上可能我安裝的一個奇怪的怪癖(去圖)。 在主機上的 shell 中使用mysql --login-path=myDbUser [etc...]我不斷收到錯誤ERROR 1045 (28000): Access denied for user 'ADMIN'@'localhost' (using password: NO)客戶端用戶是ADMIN並且我嘗試以myDbUser身份登錄。

我實際上卸載並重新安裝了 mysql (通過 Homebrew)並且仍然有相同的結果。 使用不同的機器(運行 Sierra,但相同的 mysql 版本)我可以成功運行上述 shell 命令並以目標用戶身份登錄 mysql。

同樣在主機上,我可以sudo -u _www zsh並以 Apache 用戶(即運行整個節目的用戶)身份運行命令,沒有問題。 那么為什么它既不能在腳本中正確運行,也不能以我的主要客戶端用戶身份從 Shell 中正確運行???

有任何想法嗎? $PATH在上述所有情況下都是相同的。 相同的~/.mylogin.cnf設置。 還有什么愚蠢的明顯我錯過了嗎?

您需要在此處使用間接擴展:

  echo "$(${MYSQL_COMMAND_ARRAY[@]})"

男人說:

如果參數的第一個字符是感嘆號 (!),並且參數不是 nameref,則它引入了一個變量間接級別。 Bash 使用由參數的其余部分形成的變量的值作為變量的名稱; 這個變量然后被擴展,並且該值用於替換的其余部分,而不是參數本身的值。 這稱為間接擴展。 如果 parameter 是 nameref,這將擴展為 parameter 引用的變量的名稱,而不是執行完整的間接擴展。 例外情況是下面描述的 ${!prefix*} 和 ${!name[@]} 的擴展。 感嘆號必須緊跟在左大括號之后才能引入間接性。

 ${!name[@]} ${!name[*]}

如果 name 是一個數組變量,則擴展到 name 中分配的數組索引(鍵)列表。 如果 name 不是數組,則在設置 name 時擴展為 0,否則為 null。 當使用 '@' 並且擴展出現在雙引號內時,每個鍵都擴展為一個單獨的詞。

PS:如果我可以提出一個我個人的意見,有一個 php -> python -> bash 鏈是你見過的最糟糕的編碼風格,你可能想把它改寫成單語,這樣會更容易至少追蹤進一步的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM