Bash, stdout перенаправление команд вроде scp

У меня есть bash script с некоторыми командами scp внутри. Он работает очень хорошо, но если я попытаюсь перенаправить мой stdout с помощью "./myscript.sh > log", то только явные эхо отображаются в файле журнала. Выход scp отсутствует.

if $C_SFTP; then
   scp -r [email protected]$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
fi

Хорошо, что мне теперь делать? Спасибо вам

Ответ 1

scp использует интерактивный терминал, чтобы распечатать этот яркий индикатор выполнения. Печать этого вывода в файл не имеет смысла, поэтому scp обнаруживает, когда его выход перенаправляется в другое место, кроме терминала, и отключает этот вывод.

Что имеет смысл, однако, перенаправляет вывод ошибки в файл в случае наличия ошибок. Вы можете отключить стандартный вывод, если хотите.

Есть два возможных способа сделать это. Сначала нужно вызвать ваш script с перенаправлением как stderr, так и stdout в файл журнала:

./myscript.sh >log 2>&1

Во-вторых, нужно сказать bash сделать это прямо в вашем script:

#!/bin/sh

exec 2>&1

if $C_SFTP; then
   scp -r [email protected]$C_SFTP_HOST:$C_SOURCE "$C_TMPDIR"
fi

...

Если вам нужно проверить наличие ошибок, просто убедитесь, что $? is 0 после выполнения команды scp:

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

Другой вариант - сделать set -e в script, который сообщает bash script сообщить об ошибке, как только одна из команд в сценариях завершится с ошибкой:

#!/bin/bash

set -e

...

Надеюсь, это поможет. Удачи!

Ответ 2

К сожалению, вывод 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 [email protected]:/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.

Ответ 3

Вы, кошка, просто проверяете свой tty с помощью:

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

Если это работает, попробуйте:

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

Это сработало для меня...

Ответ 4

Я нашел грубое решение для scp:

$ scp -qv [email protected]$HOST:$SRC $DEST

Согласно странице man scp, -q (quiet) отключает индикатор выполнения, а также отключает весь другой вывод. Добавьте -v (verbose), вы получите кучу вывода... и индикатор выполнения все еще отключен! Отключение индикатора выполнения позволяет перенаправить вывод в файл.

Если вам не нужен весь отладочный вывод проверки подлинности, перенаправляйте вывод на stdout и выгружайте ненужные биты:

$ scp -qv [email protected]$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 [email protected]$HOST:$SRC $DEST 2>&1 | grep -v debug > scplog.txt