调用 ssh“mysql...”时,“while read line”提前返回

调用 ssh“mysql...”时,“while read line”提前返回

我有一个脚本,它从 mysql 读取数据(下面的 get_sql_results 函数),然后我读取每一行,用 awk 解析各个列。
除了通过 ssh 将 mysql 查询的结果分配给 cmusername 的那一行之外,其他一切都运行正常。当包含此行时,只读取 $results 的第一行,并且脚本在完成第一次迭代后似乎“退出”了 while read 循环。
当我注释掉 cmusername= 行时,它会像我预期的那样显示多行。

以下是主要脚本:

new_results() {
get_sql_results

printf %s "$results" |
while read -r line 
do        
    accounttyperaw=$(echo -en "$line" | awk -F $'\t' '{print $5}')
    accountstatusraw=$(echo -en "$line" | awk -F $'\t' '{print $3}')
    accountname=$(echo -en "$line" | awk -F $'\t' '{print $4}')
    datelastchange=$(echo -en "$line" | awk -F $'\t' '{print $8}')
    cmuserid=$(echo -en "$line" | awk -F $'\t' '{print $9}')

    accounttype=$( get_account_type $accounttyperaw )
    accountstatus=$( get_account_status $accountstatusraw )
    cmusername=$(ssh -p $mysqlport username@remotemysqlserver "/usr/local/mysql/bin/mysql -hdb00 -udba -ppassword -N -e \"SELECT username from userapp.users where userapp.users.user_id rlike '$cmuserid'; \" ")

    echo -en "$domainname\t"
    echo -en "$accounttype\t"
    echo -en "$accountstatus\t"
    echo -en "$accountname\t"
    echo -en "$datelastchange\t"
    echo -en "$cmusername\t"

    echo
done 
}

new_results

编辑-已解决:

ssh 需要传递给它 -n。请参阅下面的答案。

答案1

需要在 ssh 命令中包含 -n

https://stackoverflow.com/questions/346445/bash-while-read-loop-breaking-early

 -n      Redirects stdin from /dev/null (actually, prevents reading from stdin).  This must be used when ssh is run in the background.  A common trick is to use this to run X11 programs on a remote machine.  For example, ssh -n shadows.cs.hut.fi emacs & will
         start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel.  The ssh program will be put in the background.  (This does not work if ssh needs to ask for a password or passphrase; see also the
         -f option.)

答案2

ssh在管道循环中工作的另一种方法while是使用进程替换和备用文件描述符(如果您的 Bash 版本支持这些功能)。

while read -r -u 3 line
do
    ...
    cmusername=$(ssh -p $mysqlport username@remotemysqlserver "/usr/local/mysql/bin/mysql -hdb00 -udba -ppassword -N -e \"SELECT username from userapp.users where userapp.users.user_id rlike '$cmuserid'; \" ")
    ...
done 3< <(printf %s "$results")

这还有一个额外的好处,就是不需要在循环中创建子 shell while,因此循环中设置的变量在循环结束后仍然可用。即使您不使用备用文件描述符,也可以使用此功能。

答案3

我在您的代码中没有看到右括号。这可能是问题所在吗?

    cmusername=$(ssh -p $mysqlport username@remotemysqlserver "/usr/local/mysql/bin/mysql -hdb00 -udba -ppassword -N -e \"SELECT username from userapp.users where userapp.users.user_id rlike '$cmuserid'; \" "

应该吗

    cmusername=$(ssh -p $mysqlport username@remotemysqlserver "/usr/local/mysql/bin/mysql -hdb00 -udba -ppassword -N -e \"SELECT username from userapp.users where userapp.users.user_id rlike '$cmuserid'; \" ")

相关内容