Вы попытались сжать/распаковать данные в полете? Пакеты обнуляют, должен сжаться хорошо.
На самом деле, думая об этом снова, это очень просто. На удаленном хосте создайте канал с mkfifo
. scp
/dd
к тому каналу, как обычно, и cp --sparse=always
от него до фактического конечного файла.
Протестированный на моей установке и это действительно производит редкий файл на выводе. Спасибо за деликатный вопрос!
Ksh имеет специальный параметр SECONDS
который всегда содержит число секунд с эпохи. Оценка $SECONDS
вначале и в конце задания дает Вам запуск и время окончания, и различием является прошедшее время.
Время Unix не принимает секунды прыжка во внимание: день во время Unix является всегда точно 84 000 секунд. Поэтому арифметика времени суток на времени Unix легка.
start=$SECONDS
…
end=$SECONDS
elapsed=$((end - start))
printf 'Process completed %d:%02d:%02d - Elapsed %d:%02d:%02d\n' \
$((end / 3600)) $((end / 60 % 60)) $((end % 60)) \
$((elapsed / 3600)) $((elapsed / 60 % 60)) $((elapsed % 60))
Как это (Предупреждение: те из чувствительного расположения отводят взгляд теперь - это - старая школа ksh):
t1=`date '+%H:%M:%S'`
sleep 2
t2=`date '+%H:%M:%S'`
t1h=`expr $t1 : '\(..\):.*'`
t2h=`expr $t2 : '\(..\):.*'`
t1m=`expr $t1 : '..:\(..\).*'`
t2m=`expr $t2 : '..:\(..\).*'`
t1s=`expr $t1 : '..:..:\(..\)'`
t2s=`expr $t2 : '..:..:\(..\)'`
hdiff=`expr $t2h - $t1h`
mdiff=`expr $t2m - $t1m`
sdiff=`expr $t2s - $t1s`
if [ $tm1 -gt $tm2 ];then
hdiff=`expr $hdiff - 1`
mdiff=`expr $tm1 - $tm2`
fi
if [ $ts1 -gt $ts2 ];then
mdiff=`expr $mdiff - 1`
sdiff=`expr $sm1 - $sm2`
fi
if [ $hdiff -lt 10 ];then
hdiff="0$hdiff"
fi
if [ $mdiff -lt 10 ];then
mdiff="0$mdiff"
fi
if [ $sdiff -lt 10 ];then
sdiff="0$sdiff"
fi
echo "Elapsed time $hdiff:$mdiff:$sdiff"
Извините это для удара, не заметил, что Вы хотели оболочку Korn недо сейчас, я не могу помочь с этим, но это могло бы дать Вам основной принцип.
StartTime=$( date +"%s" )
# do some stuff
sleep 4
EndTime=$( date )
ElapsedSecs=$(( `date -d"$EndTime" +%s` - StartTime ))
secs=$(( ElapsedSecs % 60 ))
mins=$(( ( ElapsedSecs / 60 ) % 60 ))
hrs=$(( ElapsedSecs / 3600 ))
EndTimeFormated=$( date -d"$EndTime" +"%H:%M:%S" )
echo "Process completed $EndTimeFormated - Elapsed " `printf "%02d:%02d%02d\n" $hrs $mins $secs`
Самый простой и чистый вариант — использоватьdate
:
date -ud "@$elapsed" "+Elapsed Time: %T"
Здесь $elapsed
представляет дельту времени в секундах.
Вы можете избежать разветвления внешнего date
процесса, придерживаясь встроенных -модулей оболочки [1][2]. Команда оболочки printf
имеет спецификатор формата даты/времени %(...)T
, который часто упускают из виду :
TZ=UTC0 printf "Elapsed Time: %(%T)T\n" $elapsed
TZ=UTC0
и date -u
устанавливают часовой пояс на UTC, что предотвращает любую двусмысленность, связанную с часовым поясом и летним временем.
Поскольку в этом вопросе особое внимание уделяется форматированию, эти методы намного удобнее и гораздо менее подвержены ошибкам, -чем вычисление частей даты, потому что у вас есть весь диапазон date
параметров формата, доступных вам -без математики. Они хорошо работают для интервалов до 24 часов и, кроме точности до -секунды, должны работать и в Bash v4.2+.
Пример:
Предположим, вы также хотите добавить наносекунды:
$ start=$SECONDS
$ #wait or run process
$ date -ud "@$((SECONDS-start))" "+Elapsed Time: %H:%M:%S.%N"
Elapsed Time: 00:00:12.003247901
$ #Or, preferably
$ TZ=UTC0 printf "Elapsed Time: %(%H:%M:%S.%N)T\n" $((SECONDS-start))
Elapsed Time: 00:00:12.005056068
Бонус
Вы можете абстрагировать свое измерение времени с помощью псевдонимов, чтобы упростить задачу. Например, мы можем эмулировать команду Oracle TIMING следующим образом:
alias timingstart='start=$SECONDS'
alias timingstop='TZ=UTC0 printf "Elapsed Time: %(%T)T\n" $((SECONDS-start))'
Итак, теперь:
$ timingstart
$ sleep 2
$ timingstop
Elapsed Time: 00:00:02
[1] Информацию о переменной $SECONDS
см. в man ksh | less +/SECONDS
. [2] Информацию о форматах времени printf
см. в man ksh | less +/date-format -j.9