【问题标题】:While loop executes only once when using rsync使用 rsync 时,while 循环只执行一次
【发布时间】:2014-06-20 19:47:30
【问题描述】:

我创建了一个 bash 脚本来将站点和数据库从一台服务器迁移到另一台服务器:算法:

  1. 解析 .pgpass 文件以为所有指定的 Postgres 数据库创建单独的转储。
  2. 通过rsync将上述转储上传到另一台服务器。
  3. 将与每个 db 相关的一堆文件夹上传到其他服务器,也可以通过 rsync。

由于数据库和文件夹具有相同的名称,如果脚本知道数据库名称,它可以预测文件夹的位置。我面临的问题是循环只执行一次(只有 .pgpass 的第一行正在完成)。

这是我的脚本,要在源服务器中运行:

#!/bin/bash

# Read each line of the input file, parse args separated by semicolon (:)
while IFS=: read host port db user pswd ; do
    # Create the dump. No need to enter the password as we're using .pgpass
    pg_dump -U $user -h $host -f "$db.sql" $db
    # Create a dir in the destination server to copy the files into
    ssh user@destination.server mkdir -p webapps/$db/static/media
    # Copy the dump to the destination server
    rsync -azhr $db.sql user@destination:/home/user
    # Copy the website files and folders to the destination server
    rsync -azhr --exclude "*.thumbnails*" webapps/$db/static/media/ user@destination.server:/home/user/webapps/$db/static/media
# At this point I expect the script to continue to the next line, but if exits at the first line
done < $1

这是.pgpass,要解析的文件:

localhost:*:db_name1:db_user1:db_pass1
localhost:*:db_name3:db_user2:db_pass2
localhost:*:db_name3:db_user3:db_pass3
# Many more...

我就是这样称呼它的:

./my_script.sh .pgpass

此时一切正常。创建第一个转储,并将其与相关文件和文件夹一起传输到目标服务器。问题是脚本在那里完成,并且不会解析.pgpass 的其他行。我已经注释掉了与rsync 相关的所有行(因此脚本只创建转储),并且它工作正常,对脚本中的每一行执行一次。如何让脚本在执行 rsync 后不退出?

顺便说一句,我使用基于密钥的 ssh 身份验证来连接服务器,因此脚本完全无需提示。

【问题讨论】:

    标签: bash ssh rsync


    【解决方案1】:

    我们问shellcheck

    $ shellcheck yourscript
    
    In yourscript line 4:
    while IFS=: read host port db user pswd ; do
    ^-- SC2095: ssh may swallow stdin, preventing this loop from working properly.
    
    In yourscript line 8:
        ssh user@destination.server mkdir -p webapps/$db/static/media
        ^-- SC2095: Add < /dev/null to prevent ssh from swallowing stdin.
    

    然后就可以了。

    【讨论】:

    • 太棒了!我只是将 -n 选项传递给 ssh,它完成了同样的事情,现在它正在工作。感谢分享 shellcheck。
    最近更新 更多