История изменений
Исправление ZyX, (текущая версия) :
К сожалению, ещё нет. Это требует реализации файловых операций вручную, а не внешними утилитами. Подходящих библиотек на C (не комбайнов вроде gtk или того, что есть у Apache) для этого найти не удалось. Планирую иметь первоначальную реализацию в каком-то виде в следующем релизе (по умолчанию будет включёна текущая реализация).
Есть хак с парсингом вывода strace: можно подсчитать, сколько байтов надо скопировать, а потом считать, сколько байтов было записано (strace -e write
после “=” выдаёт количествой записанных байт). Правда, мой вариант (cp_p: CP with Progress bar, ниже), работает не всегда корректно.
#!/bin/zsh
set -A SOURCES
typeset -g \
DEREFERENCE=""
typeset -gi \
DOHARDLINKS=0 \
DOSYMLINKS=0 \
ONEFILESYSTEM=0
typeset -ga SOURCES
function parse_args()
{
local -i SKIP=0
local -i HAS_TARGETDIR=0
local LASTSOURCE=""
for arg in $@
do
if (( SKIP ))
then
SKIP=0
continue
fi
if [[ "$arg" =~ "^-.*" ]]
then
case $arg in
--no-preserve|--reply|--sparce|--target-directory|-S|--suffix|-V|--version-control)
SKIP=1 ;;
--*)
[[ "$arg" == "--link" ]] && DOHARDLINKS=1
[[ "$arg" == "--dereference" ]] && DEREFERENCE="-L"
[[ "$arg" == "--no-dereference" ]] && DEREFERENCE=""
[[ "$arg" == "--symbolic-link" ]] && DOSYMLINKS=1
[[ "$arg" == "--one-file-system" ]] && ONEFILESYSTEM=1 ;;
-*) [[ "$arg" =~ "H" ]] && DEREFERENCE="-D"
[[ "$arg" =~ "L" ]] && DEREFERENCE="-L"
[[ "$arg" =~ "[Pd]" ]] && DEREFERENCE=""
[[ "$arg" =~ "l" ]] && DOHARDLINKS=1
[[ "$arg" =~ "s" ]] && DOSYMLINKS=1
[[ "$arg" =~ "x" ]] && ONEFILESYSTEM=1 ;;
esac
[[ "$arg" =~ "^--target-directory" ]] &&
HAS_TARGETDIR=1
else
[[ -z "$LASTSOURCE" ]] || SOURCES=( $SOURCES "$LASTSOURCE" )
LASTSOURCE="$arg"
fi
done
(( HAS_TARGETDIR )) && SOURCES=( $SOURCES $LASTSOURCE )
typeset -gr DEREFERENCE DOHARDLINKS DOSYMLINKS ONEFILESYSTEM SOURCES
}
function main()
{
parse_args $@
typeset -a KEYS
(( ONEFILESYSTEM )) && KEYS=( -x )
[[ -z "$DEREFERENCE" ]] || KEYS=( $KEYS $DEREFERENCE )
if (( ! ( DOHARDLINKS || DOSYMLINKS ) ))
then
local PGBAR FIFO
local -i line LENGTH WRITTEN=0 OLDLENGTH=-1 OLDPERCENT=-1 \
BYTES=$(du --count-links --total -b $KEYS $SOURCES | tail -n 1 | \
awk "{ print \$1 }")
# if [[ -p $HOME/.settings/cp_p-fifo ]]
# then
# FIFO=$HOME/.settings/cp_p-fifo
# else
# FIFO=$(mktmp -u)
# mkfifo $FIFO
# fi
# strace -o $FIFO -q -ewrite cp $@ >/dev/null &
# trap "kill -INT $! ; exit" INT
# cat $FIFO | grep "^write" | grep -o "[[:digit:]]\\+\$" | \
( sleep 0.1s && exec cp $@ ) &
trap "kill -INT $! ; exit" INT
strace -q -ewrite -p$! 2>&1 | grep "^write" | \
grep -o "[[:digit:]]\\+\$" | \
while read line
do
(( WRITTEN+=line ))
(( LENGTH = ((COLUMNS-7)*WRITTEN)/BYTES ))
(( PERCENT = (100*WRITTEN)/BYTES ))
(( LENGTH==OLDLENGTH && PERCENT==OLDPERCENT )) && continue
(( OLDPERCENT=PERCENT ))
echo -n "["
(( LENGTH > 1 && LENGTH!=OLDLENGTH )) && PGBAR="${PGBAR}="
(( OLDLENGTH=LENGTH ))
echo -n ${PGBAR}
(( LENGTH )) && echo -n ">"
printf "%*s] %*u%%\r" $(( COLUMNS-7-LENGTH )) "" 3 \
$PERCENT
done
else
cp $@
fi
}
main $@
Исходная версия ZyX, :
К сожалению, ещё нет. Это требует реализации файловых операций вручную, а не внешними утилитами. Подходящих библиотек на C (не комбайнов вроде gtk или того, что есть у Apache) для этого найти не удалось. Планирую иметь первоначальную реализацию в каком-то виде в следующем релизе (по умолчанию будет включёна текущая реализация).
Есть хак с парсингом вывода strace: можно подсчитать, сколько байтов надо скопировать, а потом считать, сколько байтов было записано (strace -e write[/inlite] после “=” выдаёт количествой записанных байт). Правда, мой вариант (cp_p: CP with Progress bar, ниже), работает не всегда корректно.
#!/bin/zsh
set -A SOURCES
typeset -g \
DEREFERENCE=""
typeset -gi \
DOHARDLINKS=0 \
DOSYMLINKS=0 \
ONEFILESYSTEM=0
typeset -ga SOURCES
function parse_args()
{
local -i SKIP=0
local -i HAS_TARGETDIR=0
local LASTSOURCE=""
for arg in $@
do
if (( SKIP ))
then
SKIP=0
continue
fi
if [[ "$arg" =~ "^-.*" ]]
then
case $arg in
--no-preserve|--reply|--sparce|--target-directory|-S|--suffix|-V|--version-control)
SKIP=1 ;;
--*)
[[ "$arg" == "--link" ]] && DOHARDLINKS=1
[[ "$arg" == "--dereference" ]] && DEREFERENCE="-L"
[[ "$arg" == "--no-dereference" ]] && DEREFERENCE=""
[[ "$arg" == "--symbolic-link" ]] && DOSYMLINKS=1
[[ "$arg" == "--one-file-system" ]] && ONEFILESYSTEM=1 ;;
-*) [[ "$arg" =~ "H" ]] && DEREFERENCE="-D"
[[ "$arg" =~ "L" ]] && DEREFERENCE="-L"
[[ "$arg" =~ "[Pd]" ]] && DEREFERENCE=""
[[ "$arg" =~ "l" ]] && DOHARDLINKS=1
[[ "$arg" =~ "s" ]] && DOSYMLINKS=1
[[ "$arg" =~ "x" ]] && ONEFILESYSTEM=1 ;;
esac
[[ "$arg" =~ "^--target-directory" ]] &&
HAS_TARGETDIR=1
else
[[ -z "$LASTSOURCE" ]] || SOURCES=( $SOURCES "$LASTSOURCE" )
LASTSOURCE="$arg"
fi
done
(( HAS_TARGETDIR )) && SOURCES=( $SOURCES $LASTSOURCE )
typeset -gr DEREFERENCE DOHARDLINKS DOSYMLINKS ONEFILESYSTEM SOURCES
}
function main()
{
parse_args $@
typeset -a KEYS
(( ONEFILESYSTEM )) && KEYS=( -x )
[[ -z "$DEREFERENCE" ]] || KEYS=( $KEYS $DEREFERENCE )
if (( ! ( DOHARDLINKS || DOSYMLINKS ) ))
then
local PGBAR FIFO
local -i line LENGTH WRITTEN=0 OLDLENGTH=-1 OLDPERCENT=-1 \
BYTES=$(du --count-links --total -b $KEYS $SOURCES | tail -n 1 | \
awk "{ print \$1 }")
# if [[ -p $HOME/.settings/cp_p-fifo ]]
# then
# FIFO=$HOME/.settings/cp_p-fifo
# else
# FIFO=$(mktmp -u)
# mkfifo $FIFO
# fi
# strace -o $FIFO -q -ewrite cp $@ >/dev/null &
# trap "kill -INT $! ; exit" INT
# cat $FIFO | grep "^write" | grep -o "[[:digit:]]\\+\$" | \
( sleep 0.1s && exec cp $@ ) &
trap "kill -INT $! ; exit" INT
strace -q -ewrite -p$! 2>&1 | grep "^write" | \
grep -o "[[:digit:]]\\+\$" | \
while read line
do
(( WRITTEN+=line ))
(( LENGTH = ((COLUMNS-7)*WRITTEN)/BYTES ))
(( PERCENT = (100*WRITTEN)/BYTES ))
(( LENGTH==OLDLENGTH && PERCENT==OLDPERCENT )) && continue
(( OLDPERCENT=PERCENT ))
echo -n "["
(( LENGTH > 1 && LENGTH!=OLDLENGTH )) && PGBAR="${PGBAR}="
(( OLDLENGTH=LENGTH ))
echo -n ${PGBAR}
(( LENGTH )) && echo -n ">"
printf "%*s] %*u%%\r" $(( COLUMNS-7-LENGTH )) "" 3 \
$PERCENT
done
else
cp $@
fi
}
main $@