2010-03-11 6 views
1

쉘 스크립팅의 다중 스레딩에 관한 이전 쿼리 외에도 다중 진행률 표시 줄을 사용할 수 있는지 궁금합니다. 선이 진행 상황을 보여주는 업데이트다중 진행 표시 줄

Output : 1 of 100 Files Completed # Thread1 
Output : 10 of 45 files Completed  # Thread 2  

: 여기

내 예상 된 결과의 코드입니다. 쉘을 구현하는 것이 가능할까요? 누군가이 아이디어가 있다면 도움을 주셔서 감사합니다.

감사 키란 pv -c가하는 일처럼

답변

1

?

물론, src/pv/cursor.c을 참조하십시오. 셸에서만 실제로 안전하게 수행 할 수있는 것은 아니지만 작은 C 유틸리티로 처리 할 수 ​​있습니다.

+0

쉘에서 다른 이스케이프 문자 \ n \ r 등으로 printf 문을 사용하는 것이 가능합니까 ?? – Kiran

+0

아닙니다. 두 스레드가 동시에 터미널에 쓰고 라인을 엉망으로 만드는 것을 어떻게 막을 수 있습니까? ANSI 이스케이프를 사용하여 커서 위치를 위로 올려야합니다. – ephemient

+0

예언자, 저것은 나가보고있는 무슨이다. 이것이 쉘 스크립트만으로 가능하다면 .. 너무 많이 기대하고 있습니다. 제가 할 수 있다면 좋을 것입니다 .. – Kiran

1

예, 가능합니다.

do_something() { 
    ... 
    echo -ne "\r$index of $No_of_Files Completed" 
    ... 
} 

do_something A & 
do_something B & 
do_something C & 
wait 

... 당신은 당신이 생각했던 효과를 달성하기 위해 다음과 같은 조정을 수행 할 수 있습니다 (귀하의 사전 게시물 기준) 기존의 코드는 현재 이런 식한다고 가정

:

# Background tasks will no longer write directly to the console; instead, 
# they will write to temporary files which will be read periodically 
# by a special log printer task (which will display everything nicely.) 
# 
# Name of temporary files 
STATUS_BASENAME="/tmp/~$$.status" 
# Process IDs of backgrounded tasks; we record them so we can wait on them 
# specifically but not wait on the special log printer task 
TASK_PIDS="" 

do_something() { 
    # First parameter must be a task ID starting at 0 incremented by 1 
    TASK_ID=$1 ; shift 
    ... 
    # We write new status to status file (note we don't echo -n, we want that 
    # trailing newline) 
    # Try to go through a temporary status file which we rename afterwards to 
    # avoid race conditions with the special log printer task 
    echo "$x of 5 Completed" >"${STATUS_BASENAME}.${TASK_ID}.tmp" 
    mv "${STATUS_BASENAME}.${TASK_ID}.tmp" "${STATUS_BASENAME}.${TASK_ID}" 
    ... 
} 

# Special log printer task 
status_printer() { 
    # First time in the loop is special insofar we don't have to 
    # scroll up to overwrite previous output. 
    FIRST_TIME=1 
    while true ; do 
    # If not first time, scroll up as many lines as we have 
    # regular background tasks to overwrite previous output. 
    test $FIRST_TIME -eq 0 && for PID in $TASK_PIDS ; do 
     echo -ne '\033M' # scrol up one line using ANSI/VT100 cursor control sequences 
    done 
    FIRST_TIME=0 
    TASK_ID=0 
    for PID in $TASK_PIDS ; do 
     # If status file exists print first line 
     test -f "${STATUS_BASENAME}.${TASK_ID}" && head -1 "${STATUS_BASENAME}.${TASK_ID}" || echo "waiting..." 
     TASK_ID=`expr $TASK_ID + 1` # using expr for portability :) 
    done 
    test -f "${STATUS_BASENAME}.done" && return 
    sleep 1 # seconds to wait between updates 
    done 
} 

do_something 0 A & 
TASK_PIDS="$TASK_PIDS $!" 
do_something 1 B & 
TASK_PIDS="$TASK_PIDS $!" 
do_something 2 C & 
TASK_PIDS="$TASK_PIDS $!" 

status_printer & 
    PRINTER_PID=$! 

# Wait for background tasks 
wait $TASK_PIDS 

# Stop special printer task instead of doing just 
# kill $PRINTER_PID >/dev/null 
touch "${STATUS_BASENAME}.done" 
wait $PRINTER_PID 

# Cleanup 
rm -f "${STATUS_BASENAME}."* 
+0

이 코드를 개발할 때 시간을내어 주셔서 감사합니다. 나는 이것을 시도 할 것입니다. 내 프레임 워크에 맞는지 확인하십시오. echo와 printf 문을 조합하여 사용하는 확실한 방법이 있다면 나는 생각하고 있었다. 모든 도움을 감사하십시오. – Kiran

0

당신의 서브 프로세스 출력 필터링의 경우, 다른 파일 기술자 각 subproc의 표준 출력을 리디렉션 할 수 있으며, 그 파일 기술자의 출력을 반복하는 함수를 호출 할 수 있습니다. 그런 다음 printf를 사용하여 진행률 측정기를 업데이트 할 수 있습니다. 이것은 당신이 곤경에 처하게 될 곳입니다. Bash의 내장 printf가 터미널을 자세히 처리 할 수 ​​있는지 확신 할 수 없습니다. 필자는 Bash에서 멀티 라인 출력을하는 진행률 미터를 쓰려고 시도한 적이 없습니다. 왜 대화 상자를 사용하지 않습니까?