انجمن‌های فارسی اوبونتو

کمک و پشتیبانی => راهنماها، نکات و ترفندها => نویسنده: nino در 07 شهریور 1397، 03:29 ب‌ظ

عنوان: اسکریپت برای کپی و نمایش همزمان progress bar (حل شد)
ارسال شده توسط: nino در 07 شهریور 1397، 03:29 ب‌ظ
سلام.
یک اسکریپت ساده داریم برای کپی فایل، حاوی دو بخش:
اول، فرمان کپی فایل های مورد نظر. مثلا:
دوم: یک progress bar (که در اینجا به شکل یک / چرخانه):
cp -r /home/user/Photos /home/user/Backup

i=1
sp="/-\|"
echo -n ' '
        while true
        do
        printf "\b${sp:i++%${#sp}:1}"
        done

مشکل اینجاست که نمی دونم چطور هر دو تا دستور با هم انجام بشه.
یعنی در حین انجام شدن کپی، اون progress bar هم نشون داده بشه و با اتمام کپی قطع بشه، اما الان اینجوریه که کپی باید تموم بشه تا بخش بعدی شروع به کار بکنه.
گزینه دیگه هم اینه که فرمان کپی رو بزارم آخر اسکریپت ولی فرمان progress bar به صورت لوپه و همینطور به چرخیدن ادامه میده.
حتی بین این دو دستور از & هم استفاده کردم تا همزمان انجام بشن اما تاثیری نداشت.
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: SMAH1 در 07 شهریور 1397، 03:36 ب‌ظ
سلام
در برنامه نویسی مفهومی داریم به نام forking که به نظرم باید اینجا استفاده بشه.
دو نمونه لینک می‌آورم ولی باید بیشتر جستجو کنی:
https://unix.stackexchange.com/questions/7608/does-bash-support-forking-similar-to-cs-fork (https://unix.stackexchange.com/questions/7608/does-bash-support-forking-similar-to-cs-fork)
https://stackoverflow.com/questions/3096561/fork-and-exec-in-bash (https://stackoverflow.com/questions/3096561/fork-and-exec-in-bash)
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: علی رزم دیده در 07 شهریور 1397، 10:17 ب‌ظ
سلام

اول یه سری مباحث رو توضیح می دم بعدش می رم سر قسمت اصلی کد :

1.اگه شما دستورات رو به همون صورت که نوشتین (و یا به صورت command 1 ; command 2) اجرا کنین ، این دستورات دقیقاً به همین ترتیبی که نوشته شدن اجرا می شن.
یعنی اول دستور اول اجرا می شه بعدش دستور بعدی و ....


2.چون گفتین بین دستورات && رو گذاشتین ، این رو هم بهتره توضیح بدم :
وقتی از && استفاده می کنیم اینجا هم عین حالت قبل اول دستور اول و بعدش دستور دوم اجرا می شه منتهی تفاوتش اینه که دستور دوم تنها و تنها زمانی اجرا می شه که دستور اول با موفقیت اجرا بشه.


ولی چیزی که شما می خواین این هستش که هر دو دستور همزمان اجرا بشن.
برای اینکار شما باید دستور اول رو به پس زمینه منتقلش کنین تا بلافاصله دستورات بعدی اجرا بشن. (برای اینکار راه های مختلفی مثل استفاده از & و یا nohup وجود داره)

ولی شما یه چیز دیگه ای هم می خواین و اونم اینه که دستور دوم تا زمانی اجرا بشه که دستور اول در حال اجرا هستش.
برای این کار هم راه زیاد داریم ولی یکی از بهترین راه ها اینه که pid مربوط به دستور اول رو توی یه متغیر نیگه داریم و به جای while true (که در واقع حلقه ی بی نهایت هستش) از ساختاری استفاده کنیم که تا زمانی که اون pid موجود هستش دستورات اجرا بشن.

برای این کار می تونین از این اسکریپت استفاده کنیم (من سعی کردم دستوری رو که شما نوشتین رو با کمترین تغییر اصلاح کنم و به ساختارش دست نزنم) :

cp -r /home/user/Photos /home/user/Backup &
pid=$!

i=1
sp="/-\|"
echo -n ' '

while ps -p $pid &>/dev/null ; do
    printf "\b${sp:i++%${#sp}:1}"
done


پ.ن 1: برای اینکار که می خواین انجام بدین ( progress bar در کپی فایل) راه های بهتری هم وجود داره مثلا استفاده از rsync و pv و dd و ...
که می تونین از اونا استفاده کنین.


پ.ن 2:توی حلقه تون حتماً حتماً از sleep استفاده کنین وگرنه اینی که شما نوشتین بار زیادی رو به پردازنده تحمیل می کنه و اینو می تونین از طریق htop موقع اجرای اسکریپت چک کنین.
توصیه ی من چنین ساختاری هستش :
while true ; do
    sleep 0.1s;
    printf "\b${sp:i++%${#sp}:1}"
done
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: Silvio Dante در 07 شهریور 1397، 10:50 ب‌ظ
توضیحات آقای رزم دیده خیلی خوب و کامل بود.
این اسکریپت هم چیزی بود که من وقتی تاپیک‌تون رو دیدم برام جالب شد ببینم چجوری می‌شه همچین کاری انجام داد که با کمی سرچ توی اینترنت و رسیدن به همین pidای که آقای رزم دیده گفتن، نوشتمش، و همچنین خروجی progress barهم کمی متفاوته (بنظرم این حالت جذاب‌تر بود) که البته می‌تونین مال خودتون رو جایگزین کنین:
#!/bin/bash
cp -a ~/Photos ~/Backup &
pid=$!

trap "kill $pid 2> /dev/null" EXIT
spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"

echo -n "[copying] ${spin[0]}"
while kill -0 $pid 2> /dev/null
do
  for i in "${spin[@]}"
  do
        echo -ne "\b$i"
        sleep 0.1
  done
done

trap - EXIT
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: nino در 07 شهریور 1397، 10:57 ب‌ظ
برای این کار می تونین از این اسکریپت استفاده کنیم (من سعی کردم دستوری رو که شما نوشتین رو با کمترین تغییر اصلاح کنم و به ساختارش دست نزنم) :

cp -r /home/user/Photos /home/user/Backup &
pid=$!

i=1
sp="/-\|"
echo -n ' '

while ps -p $pid &>/dev/null ; do
    printf "\b${sp:i++%${#sp}:1}"
done
بله این دقیقا چیزیه که مدنظر من بود و به خوبی جواب میده.  =D>
البته این خط رو هم به آخر اسکریپت اضافه کردم که بعد از تموم شدن کار کپی، کاراکترهای خط قبلش رو کامل پاک کنه:
echo -en "\033[1K\r"
پ.ن 1: برای اینکار که می خواین انجام بدین ( progress bar در کپی فایل) راه های بهتری هم وجود داره مثلا استفاده از rsync و pv و dd و ...
که می تونین از اونا استفاده کنین.
pv و bar رو امتحان کردم ولی واسه من کار نمی کردن. pv نوارش ثابت بود و هیچ حرکتی نداشت. فقط تونستم از تایمرش استفاده کنم، که به درد کار من نمی خورد.
rsync و dd رو هم حتما امتحان می کنم. گزینه های خوبین. توی سایت های دیگه هم زیاد پیشنهاد شده بودن.
در مورد sleep هم حق با شماست. باید اضافه بشه.

تشکر بسیار زیاد.
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: nino در 07 شهریور 1397، 11:06 ب‌ظ
#!/bin/bash
cp -a ~/Photos ~/Backup &
pid=$!

trap "kill $pid 2> /dev/null" EXIT
spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"

echo -n "[copying] ${spin[0]}"
while kill -0 $pid 2> /dev/null
do
  for i in "${spin[@]}"
  do
        echo -ne "\b$i"
        sleep 0.1
  done
done

trap - EXIT
الان اینو هم امتحان کردم ولی واسه من هیچ progress bar نشون نداد.
نیاز به نصب نرم افزار خاصی داره؟!
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: Silvio Dante در 08 شهریور 1397، 02:15 ق‌ظ
الان اینو هم امتحان کردم ولی واسه من هیچ progress bar نشون نداد.
نیاز به نصب نرم افزار خاصی داره؟!
نه نرم افزار خاصی نمی‌خواد. احتمالا فایل‌ها‌تون رو یه بار کپی کردین و دیگه چیزی نبوده کپی کنه. عکس متحرک ضمیمه شده رو نگاه کنین اینجوریه خروجیش.
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: nino در 08 شهریور 1397، 09:27 ق‌ظ
نه نرم افزار خاصی نمی‌خواد. احتمالا فایل‌ها‌تون رو یه بار کپی کردین و دیگه چیزی نبوده کپی کنه. عکس متحرک ضمیمه شده رو نگاه کنین اینجوریه خروجیش.
آره اینم چرخانه. الان دوباره امتحان کردم درست بود.
اولی به نظر کمی ساده تر نوشته شده. حالا با توجه به این که این دو تا متفاوت از هم نوشته شدن، شما کدوم رو پیشنهاد می دید؟
عنوان: پاسخ : اسکریپت برای کپی و نمایش همزمان progress bar
ارسال شده توسط: Silvio Dante در 08 شهریور 1397، 02:15 ب‌ظ
آره اینم چرخانه. الان دوباره امتحان کردم درست بود.
اولی به نظر کمی ساده تر نوشته شده. حالا با توجه به این که این دو تا متفاوت از هم نوشته شدن، شما کدوم رو پیشنهاد می دید؟
فرق خاصی ندارن هر دو یک کار یکسان رو انجام می‌دن فقط اونی که من نوشتم ظاهر خروجی‌ش تفاوت داره. از ظاهر هر کدوم که خوشتون میاد استفاده کنین.