【问题标题】:Bash, stdout redirect of commands like scpBash,stdout 重定向命令,如 scp
【发布时间】:2010-10-08 13:11:41
【问题描述】:

我有一个 bash 脚本,里面有一些 scp 命令。 它工作得很好,但是,如果我尝试使用“./myscript.sh >log”重定向我的标准输出,那么“日志”文件中只会显示我的显式回显。 缺少 scp 输出。

if $C_SFTP; then
   scp -r $C_SFTP_USER@$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
fi

好的,我现在该怎么办? 谢谢

【问题讨论】:

    标签: bash redirect stdout


    【解决方案1】:

    scp 正在使用交互式终端来打印那个精美的进度条。将该输出打印到文件根本没有意义,因此scp 会检测其输出何时被重定向到终端以外的其他位置并禁用此输出。

    然而,有意义的是将其错误输出重定向到文件中,以防出现错误。如果需要,您可能希望禁用标准输出。

    有两种可能的方法来做到这一点。首先是通过将 stderr 和 stdout 重定向到日志文件来调用您的脚本:

    ./myscript.sh >log 2>&1
    

    其次,是告诉 bash 在你的脚本中正确执行此操作:

    #!/bin/sh
    
    exec 2>&1
    
    if $C_SFTP; then
       scp -r $C_SFTP_USER@$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
    fi
    
    ...
    

    如果需要检查错误,只需在scp命令执行后验证$?0即可:

    if $C_SFTP; then
       scp -r $C_SFTP_USER@$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
       RET=$?
       if [ $RET -ne 0 ]; then
          echo SOS 2>&1
          exit $RET
       fi
    fi
    

    另一种选择是在您的脚本中执行set -e,这会告诉 bash 脚本在脚本中的一个命令失败时立即报告失败:

    #!/bin/bash
    
    set -e
    
    ...
    

    希望对您有所帮助。祝你好运!

    【讨论】:

    • if [ "$RET" -ne "0" ]; then.. 0 附近不需要 ",-ne/-eq 将测试整数值。
    • @Anders:只是一种习惯。改变了。
    【解决方案2】:

    你只用以下方式测试你的 tty:

    [ ~]#echo "hello" >/dev/tty
    hello
    

    如果可行,请尝试:

    [ ~]# scp <user>@<host>:<source> /dev/tty 2>/dev/null
    

    这对我有用...

    【讨论】:

    • 我试图过滤掉“将 永久添加到已知主机列表”消息,但想显示传输信息。重定向到 /dev/tty 为我工作:scp -o StrictHostKeyChecking=no localfile remotesystem:/dir/remotefile 2&gt;&amp;1 &gt;/dev/tty | grep -v "Warning: Permanently added"
    【解决方案3】:

    不幸的是,SCP 的输出似乎不能简单地重定向到标准输出。

    我想获得我的 SCP 传输的平均传输速度,而我能做到这一点的唯一方法是将 stderr 和 stdout 发送到一个文件,然后再次将文件回显到 stdout。

    例如:

    #!/bin/sh
    echo "Starting with upload test at `date`:"
    
    scp -v -i /root/.ssh/upload_test_rsa /root/uploadtest.tar.gz speedtest@myhost:/home/speedtest/uploadtest.tar.gz > /tmp/scp.log 2>&1
    grep -i bytes /tmp/scp.log
    rm -f /tmp/scp.log
    
    echo "Done with upload test at `date`."
    

    这将导致以下输出:

    Starting with upload test at Thu Sep 20 13:04:44 SAST 2012:
    Transferred: sent 10191920, received 5016 bytes, in 15.7 seconds
    Bytes per second: sent 650371.2, received 320.1
    Done with upload test at Thu Sep 20 13:05:04 SAST 2012.
    

    【讨论】:

    • 如果在将 stdout 传输到 grep 之前将 stderr 重定向到 stdout (2&gt;&amp;1),则不需要临时文件,例如:scp -v ... 2&gt;&amp;1 | grep -i bytes
    【解决方案4】:

    我为 scp 找到了一个粗略的解决方案:

    $ scp -qv $USER@$HOST:$SRC $DEST
    

    根据 scp 手册页,-q(安静)禁用进度表,以及禁用所有其他输出。也添加-v(详细),你会得到大量的输出......并且进度表仍然被禁用!禁用进度表允许您将输出重定向到文件。

    如果您不需要所有身份验证调试输出,请将输出重定向到 stdout 并 grep 出您不需要的位:

    $ scp -qv $USER@$HOST:$SRC $DEST 2>&1 | grep -v debug
    

    最终输出是这样的:

    Executing: program /usr/bin/ssh host myhost, user (unspecified), command scp -v -f ~/file.txt
    OpenSSH_6.0p1 Debian-4, OpenSSL 1.0.1e 11 Feb 2013
    Warning: Permanently added 'myhost,10.0.0.1' (ECDSA) to the list of known hosts.
    Authenticated to myhost ([10.0.0.1]:22).
    Sending file modes: C0644 426 file.txt
    Sink: C0644 426 file.txt
    Transferred: sent 2744, received 2464 bytes, in 0.0 seconds
    Bytes per second: sent 108772.7, received 97673.4
    

    另外,这可以重定向到一个文件:

    $ scp -qv $USER@$HOST:$SRC $DEST 2>&1 | grep -v debug > scplog.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多