Bash,像scp这样的命令的stdout重定向

8
我有一个包含一些scp命令的bash脚本。 它工作得非常好,但是如果我尝试使用“./myscript.sh >log”重定向我的标准输出,只有我明确输出的内容会显示在“log”文件中。 scp的输出会消失。
if $C_SFTP; then
   scp -r $C_SFTP_USER@$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
fi

好的,现在我该做什么?谢谢。
4个回答

8

scp是使用交互式终端来打印那个时尚的进度条。将该输出打印到文件中毫无意义,因此scp会检测其输出是否重定向到终端以外的其他位置,并禁用此输出。

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

有两种可能的方法来实现这一点。第一种方法是在将标准错误和标准输出重定向到日志文件的同时调用您的脚本:

./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

...

希望这能有所帮助。祝你好运!

1
如果 [ "$RET" -ne 0 ]; then.. 不需要在0周围加上引号,-ne/-eq将测试整数值。 - Anders
@Anders:只是个习惯。已经改了。 - user405725

5
您可以使用以下命令轻松测试您的tty:
[ ~]#echo "hello" >/dev/tty
hello

如果那样行得通,尝试:
[ ~]# scp <user>@<host>:<source> /dev/tty 2>/dev/null

这对我来说已经奏效了...



1
我试图过滤掉“永久添加<计算机名称>到已知主机列表”的消息,但仍想显示传输信息。将重定向到/dev/tty对我很有用:scp -o StrictHostKeyChecking=no localfile remotesystem:/dir/remotefile 2>&1 >/dev/tty | grep -v "Warning: Permanently added" - jaume

2

不幸的是,SCP的输出似乎无法直接重定向到stdout。

我想获取我的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>&1),则不需要临时文件,例如:scp -v ... 2>&1 | grep -i bytes - user_

2
我找到了一个粗略的scp解决方案。
$ scp -qv $USER@$HOST:$SRC $DEST

根据SCP手册,-q(安静)禁用进度表以及所有其他输出。 如果再加上-v(详细),你将获得大量输出……并且仍然禁用进度表! 禁用进度表允许您将输出重定向到文件中。如果您不需要所有身份验证调试输出,请将输出重定向到标准输出并筛选掉不需要的部分:
$ 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接