scp 和检查新文件之间是否可能存在延迟

scp 和检查新文件之间是否可能存在延迟

有一个定期下载东西的 cronjob:

if ! su scpuser -c "scp ..." > /dev/null 2>&1 || ! [ -f $scptarget ]; then;
  error "did not download stuff"

$scptarget是下载内容的位置,并且它与正在运行的脚本位于不同的卷上(但不是不同的状态,我认为是相同的硬盘驱动器)

每次出错时,我们都会进去查看,文件就在那里。如果稍微放松一下,检查文件是否存在的部分是否有可能成功?或者,即使 SCP 成功了,它也会抛出错误吗?

(我希望最初写这篇文章的人能记录下实际的错误是什么,我只是抓住了救命稻草)

如果是这样,我不想sleep在这个脚本中添加任意内容,是否有真正的 bash 程序员所做的更经典的事情?

答案1

stracescp一个文件做了一个。在我看来,它不像scp那样使用临时文件名wget,它实际上检查目标文件是否存在,并使用O_WRONLY|O_CREAT.如果scp实际有数据要写出,则目标文件应该存在。

目标文件存在和检查其存在之间不可能发生“竞争”。 shell 必须在scp退出时获得 SIGCHLD 才能获取退出状态并确定状态为非零。我很确定内核会在进程退出时处理现有的文件名scp。文件创建应该是原子的。不要费心添加一个sleep,它没有帮助。

示例代码到达目标文件存在性测试 ( [ -f $scptarget ]) 的唯一方法是以scp0(零)状态退出。该文件当然可能存在,但存在错误情况。$scptarget当发生错误时,您是否检查文件的正确性和完整性?您可能会得到不完整的或损坏的文件。

我认为要弄清楚发生了什么,您必须使用 2 个if构造,第一个用于 的退出状态scp,第二个用于目标文件的存在。确保消息不同,并且您记录了进程$?的退出状态scp

答案2

首先获取错误代码(stderr 也可能很有用。谁制作的脚本不记录错误...?)。 'su' 或 'scp' 可能返回 retVal>0。

OSX 的 SCP 源代码片段:

 // I'd put my bet for this case..
 void
 lostconn(signo)
    int signo;
 {
    if (!iamremote)
        fprintf(stderr, "lost connection\n");
    exit(1);
 }

确保失败后目标文件与源文件完全相同...

摘自联机帮助页:

退出价值

成功后,su 返回其执行的命令的退出值。

如果该命令由信号终止,则 su 返回该信号的编号加 128。

如果 su 必须终止该命令(因为它被要求终止,而该命令没有及时终止),su 将返回 255。

再次..如果没有退出代码或 stderr 内容,除了继续猜测之外我们无能为力。

相关内容