2015-06-19 54 views
2

我刚刚接触bash脚本,现在我正在研究一个bash脚本,它应该使用scp命令从服务器下载文件列表。但是,不能保证该文件在那里,所以我希望能够输出未找到的文件列表。目前,我这样做是为了输出错误信息:程序结束时的Bash输出

for FILENAME in [email protected] do 
scp $SERVER:/home/usr/$FILENAME . 
    if [ $? -ne 0 ] then 
    echo "WARNING: $FILENAME was not found in $SERVER." 
    fi 
done 

上面的代码工作,据我所知,但我遇到的问题是,由于如何SCP的作品,还有的已经将是一吨(因为每个scp命令将显示100%下载的行),并且我可能会错过一两条警告消息。有没有简单的方法让我最终打印所有警告消息,并列出哪些文件未找到?

编辑:我忘了说明为什么我使用回声而不是默认的“文件未找到” - 我的代码实际上应该在多个位置查找,如果它无法在第一个位置找到它。所以,更完整的版本看起来有点像这样:

for FILENAME in [email protected] do 
scp $SERVER:/home/usr/$FILENAME . 
    if [ $? -ne 0 ] then 
     scp $SERVER:/home/usr/documents/$FILENAME . 
     if [ $? -ne 0 ] then 
     scp $SERVER:/home/usr/documents/local/$FILENAME . 
     if [ $? -ne 0 ] then 
      echo "WARNING: $FILENAME was not found in $SERVER." 
     fi 
     fi 
    fi 
done 

如果没有在第一位置上找到它,这很好,但我只希望它抛出一个错误,如果我不能找到它在任何地点。

+0

使用'-q'来告诉'scp'安静?在最后再次循环参数并查看本地文件是否存在?不要回应'if'追加到数组变量并在最后打印该数组?改为回到标准错误,并将其传递到文件或管道标准输出到'/ dev/null'从'scp'? –

+0

@Etan Reisner:似乎'-q'只隐藏进度表,而不是stderr。 –

+0

来自scp的关于文件不存在/失败的stderr可能是OP实际需要的信息(因为它为他们完成了工作)。除非scp提供stderr上的其他非失败信息,也就是说。 –

回答

1

最简单的(虽然不是最有效的解决方案)是简单地检查文件最后的存在。

原始循环后补充一点:

for FILENAME in [email protected] do 
    if [ -s "$FILENAME" ] then 
     echo "WARNING: $FILENAME was not found in $SERVER." >&2 
    fi 
done 

或者如果正常SCP输出不是有趣的(你不关心其他潜在的SCP失败),那么原来的循环可能会成为:

for FILENAME in [email protected] do 
scp -q $SERVER:/home/usr/$FILENAME . 2>/dev/null 
    if [ $? -ne 0 ] then 
     scp -q $SERVER:/home/usr/documents/$FILENAME . 2>/dev/null 
     if [ $? -ne 0 ] then 
     scp -q $SERVER:/home/usr/documents/local/$FILENAME . 2>/dev/null 
     if [ $? -ne 0 ] then 
      echo "WARNING: $FILENAME was not found in $SERVER." 
     fi 
     fi 
    fi 
done 

如果你想SCP输出(正常或错误或两者),但也希望丢失的文件在最后一个简洁的列表,你可以这样做:

missing_files=() 
for FILENAME in [email protected] do 
scp $SERVER:/home/usr/$FILENAME . 
    if [ $? -ne 0 ] then 
     scp $SERVER:/home/usr/documents/$FILENAME . 
     if [ $? -ne 0 ] then 
     scp $SERVER:/home/usr/documents/local/$FILENAME . 
     if [ $? -ne 0 ] then 
      missing_files+=("$FILENAME") 
     fi 
     fi 
    fi 
done 

echo 'Missing files:' 
printf %s\\n "${missing_files[@]}" 
+0

最后一个是我正在寻找的;谢谢! – Glamdring

3

你可以在脚本的末尾scp命令的标准错误重定向到一个文件,然后cat出来的文件:

for FILENAME in [email protected] do 
scp $SERVER:/home/usr/$FILENAME . 2>> /some/dir/error.log 
    if [ $? -ne 0 ] then 
    echo "WARNING: $FILENAME was not found in $SERVER." 
    fi 
done 

cat /some/dir/error.log 
rm /some/dir/error.log 
+2

'2 >>/some/dir/error.log'? –

+0

好的。我们正在循环。纠正。 – JNevill

+0

2 >>中的数字2是什么意思? 2 >> /some/dir/error.log似乎将所有的输出结果放到一个日志文件中,然后输出它,但我只需要知道哪些文件在所有列出的文件中都找不到位置(请参阅我的原始帖子上的编辑) – Glamdring