Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 多进度条_Linux_Multithreading_Bash_Unix_Progress Bar - Fatal编程技术网

Linux 多进度条

Linux 多进度条,linux,multithreading,bash,unix,progress-bar,Linux,Multithreading,Bash,Unix,Progress Bar,除了我之前关于shell脚本中多线程的查询外,我还想知道是否可能有多个进度条 以下是我预期结果的代码片段: Output : 1 of 100 Files Completed # Thread1 Output : 10 of 45 files Completed # Thread 2 显示进度的行已更新。是否可以在shell中实现它?就像-c所做的那样 当然,看。虽然它不是仅从shell就可以安全地实现,但是一个小型的C实用程序可以处理它。就像-C所做的那样 当然,看。虽

除了我之前关于shell脚本中多线程的查询外,我还想知道是否可能有多个进度条

以下是我预期结果的代码片段:

Output : 1 of 100  Files Completed   # Thread1
Output : 10 of 45 files Completed     # Thread 2    
显示进度的行已更新。是否可以在shell中实现它?

就像
-c
所做的那样

当然,看。虽然它不是仅从shell就可以安全地实现,但是一个小型的C实用程序可以处理它。

就像
-C
所做的那样


当然,看。虽然仅在shell中并不安全,但是一个小型的C实用程序可以处理它。

是的,这是非常有可能的

假设您现有的代码(基于您以前的帖子)当前是这样的:

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}."* 

是的,很有可能

假设您现有的代码(基于您以前的帖子)当前是这样的:

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}."* 

如果您的子流程输出是可过滤的,那么您可以将每个子流程的stdout重定向到不同的文件描述符,然后调用函数来循环该文件描述符的输出。然后您可以尝试使用printf更新进度表。这就是你会遇到麻烦的地方。不确定Bash的内置printf是否能够处理终端的细节。我从未尝试在Bash中编写一个可以进行多行输出的进度表。为什么不使用对话框?

如果您的子流程输出是可过滤的,那么您可以将每个子流程的标准输出重定向到不同的文件描述符,然后调用函数循环该文件描述符的输出。然后您可以尝试使用printf更新进度表。这就是你会遇到麻烦的地方。不确定Bash的内置printf是否能够处理终端的细节。我从未尝试在Bash中编写一个可以进行多行输出的进度表。为什么不使用dialog?

shell中的printf语句是否可以使用不同的转义字符\n\r等?不太可能。如何防止两个线程同时向终端写入数据,并将线路弄乱?你必须使用ANSI转义来设置光标在一条线上的位置。是的,这就是我所看到的。如果可以,请单独使用shell脚本。。我知道,我期望太高了。。如果我能做到这一点就太好了..是否可以在shell中使用具有不同转义字符的printf语句\n\r等..不太可能。如何防止两个线程同时向终端写入数据,并将线路弄乱?你必须使用ANSI转义来设置光标在一条线上的位置。是的,这就是我所看到的。如果可以,请单独使用shell脚本。。我知道,我期望太高了。。如果我能做到那就太好了。非常感谢您抽出时间来开发这段代码。。如果它符合我的框架,我会尝试这个。我在想,是否有什么明显的方法可以结合使用echo和printf语句。感谢您的帮助非常感谢您抽出时间来开发此代码。。如果它符合我的框架,我会尝试这个。我在想,是否有什么明显的方法可以结合使用echo和printf语句。谢谢你的帮助