• Boolean و در یک bash while حلقه. چرا حلقه for در دایرکتوری اجرا نمی شود؟ مثال: فایل های اجرایی را جستجو کنید

    برای VAR که در 1 2 3... ن انجام دادن انجام شدهیا در یک خط: برای VAR که در 1 2 3...N; انجام دادن ; انجام شده
    می توان هم مقادیر عددی و هم کاراکترهای ASCII را در متغیر جایگزین کرد.
    مثال: $ برای i در 1 2 A B Abc ; انجام echo $i; انجام شد 1 2 A B Abc مثالی از فهرست کردن فایل‌ها در یک متغیر با «ماسک» برای رمزگذاری ویدیو: برایمن که در*.avi; انجام دادن ; انجام شده

    2. جایگزین کردن نتایج یک دستور دیگر

    برای VAR که در $(); انجام دادن ; انجام شده
    مثالی از استفاده از نتایج دستور seq: برایمن که در$(دنباله [KEY]); انجام دادن echo $i; انجام شده$ برای i در $ (دنباله 3); انجام echo $i; انجام شد 1 2 3 $ برای i در $ (دنباله 3 5); انجام echo $i; انجام شد 3 4 5 $ برای i در $ (دنباله 2 2 6); انجام echo $i; انجام شد 2 4 6 مثالی از استفاده از نتایج دستور ls: $ برای i در $(ls /$HOME/Video); انجام echo $i; انجام شده 001.avi 002.avi 003.avi

    3. تعویض با استفاده از سبک C (سبک C)

    برای((EXPR1; EXPR2; EXPR3)) انجام دادن <список команд> انجام شده برای((i=1; i<=3 ; i++)); انجام دادن echo $i; انجام شده$ برای ((i=1; i<=3 ; i++)); do echo $i; done 1 2 3 Подробнее о применении C-style в Bash

    4. شمارش با استفاده از بریس های مجعد (..)

    نحو (START..END) با شروع bash نسخه 3.0 و بالاتر، و نحو (START..END..INCREMENT) با شروع bash نسخه 4.0 و بالاتر پشتیبانی می شود:

    برای VAR که در {..} انجام دادن انجام شدهیا برای VAR که در {....} انجام دادن انجام شدهمثال: $ برای i در (1..3); انجام echo $i; انجام شد 1 2 3 یا $ برای i in (4..8..2); انجام echo $i; انجام شد 4 6 8 شمارش هم برای افزایش و هم برای کاهش مقادیر امکان پذیر است: $ برای i در (6..-4..3); انجام echo $i; انجام شد 6 3 0 -3

    5. جایگزینی پارامتر ( که در "$@")

    برای هر پارامتری که به اسکریپت ارسال شده است دستورات را اجرا می کند. برای VAR که در $@ انجام دادن انجام شدهیا در یک خط: برای VAR که در $@; انجام دادن ; انجام شده
    بنابراین اگر یک اسکریپت test.sh ایجاد کنید #!/bin/sh برای VAR که در $@ انجام دادن اکو VAR $ انجام شدهسپس وقتی آن را با پارامترها اجرا می کنید: $ ./test.sh param1 param2 param3 param1 param2 param3 قسمت که در$@ را می توان حذف کرد. سپس اسکریپت test.sh بازنویسی می شود: #!/bin/sh برای VAR انجام دادن اکو VAR $ انجام شده
    اجازه دهید چند مثال برای شما بزنم (با که درو بدون): تابع $ FUNC_1 ( برای VAR در $@؛ انجام پژواک $VAR؛ انجام شد؛ ) $ FUNC_1 param1 param2 param3 param1 param2 param3 تابع $ FUNC_2 ( برای VAR؛ انجام echo $VAR؛ انجام شد؛ ) $ FUNC_2 param1 param2 param3 param1 param2 param3

    6. از ادامه و شکستن در یک حلقه for استفاده کنید

    برای تمام ساختارهای بالا، می توان از دستورات "continue" برای انتقال به عنصر بعدی حلقه یا "break" برای خروج از حلقه استفاده کرد.

    مثال (وقتی i=6 کامل شود و وقتی i=3 و i=5 اجرا نشود): برایمن در (1..8); انجام دادن اگر[ $i -eq 6 ]; سپسزنگ تفريح؛ فی اگر[ $i -eq 3 ] || [ $i -eq 5 ]; سپسادامه هید؛ fi echo $i انجام شدهنتیجه اجرا: $ $ برای i in (1..8); انجام دهید \ > اگر [ $i -eq 6 ]; سپس شکستن؛ fi; \ > اگر [ $i -eq 3 ] || [ $i -eq 5 ]; سپس ادامه دهید؛ fi; \ > echo $i; \ > انجام شد 1 2 4

    توجه:مزایایی در پست پنهان است!

    برای حلقه ها

    پوسته bash از حلقه‌ها پشتیبانی می‌کند، که به شما امکان می‌دهد روی دنباله‌ای از مقادیر را تکرار کنید. در اینجا ساختار اصلی چنین حلقه هایی وجود دارد:

    برای var در لیست دستور do انجام شد

    در هر تکرار از حلقه، مقدار بعدی از لیست روی متغیر var نوشته می شود. بنابراین اولین پاس حلقه از اولین مقدار از لیست استفاده می کند. در دوم - دوم و غیره - تا زمانی که حلقه به آخرین عنصر برسد.

    تکرار بر روی مقادیر ساده

    شاید ساده‌ترین مثال حلقه for در اسکریپت‌های bash تکرار بر روی فهرستی از مقادیر ساده باشد:

    #!/bin/bash برای var در اول دوم سوم چهارم پنجم do echo مورد $var انجام شد

    نتایج این اسکریپت در زیر نشان داده شده است. شما به وضوح می بینید که متغیر $var شامل عناصری از لیست به صورت متوالی است. این اتفاق می افتد تا زمانی که چرخه به آخرین آنها برسد.



    ساده برای حلقه

    لطفا توجه داشته باشید که متغیر $var هنگام خروج از حلقه مقدار خود را حفظ می کند، محتویات آن قابل تغییر است و به طور کلی می توانید مانند هر متغیر دیگری با آن کار کنید.

    تکرار بر روی مقادیر پیچیده

    فهرستی که برای مقداردهی اولیه حلقه for استفاده می‌شود، نه تنها می‌تواند شامل رشته‌های ساده متشکل از یک کلمه، بلکه کل عباراتی باشد که حاوی چندین کلمه و علائم نگارشی هستند. به عنوان مثال، ممکن است به شکل زیر باشد:

    #!/bin/bash برای var در اولین "دومین" "سوم" "I’ll do it" echo "This is: $var" انجام شد

    این چیزی است که پس از اینکه این حلقه از لیست عبور می کند اتفاق می افتد. همانطور که می بینید، نتیجه کاملاً قابل انتظار است.



    تکرار بر روی مقادیر پیچیده
    TNW-CUS-FMP - کد تبلیغاتی برای 10٪ تخفیف در خدمات ما، برای فعال سازی ظرف 7 روز در دسترس است.

    راه اندازی یک حلقه با لیستی که از نتایج فرمان بدست می آید

    راه دیگر برای مقداردهی اولیه یک حلقه for این است که به آن لیستی ارسال کنید که نتیجه یک دستور است. در اینجا از جایگزینی دستور برای اجرای آنها و به دست آوردن نتایج کار آنها استفاده می شود.

    #!/bin/bash file="myfile" برای var در $(cat $file) echo "$var" انجام شد

    این مثال از دستور cat استفاده می کند که محتویات یک فایل را می خواند. لیست حاصل از مقادیر به حلقه منتقل می شود و روی صفحه نمایش داده می شود. لطفاً توجه داشته باشید که فایلی که ما به آن دسترسی داریم حاوی لیستی از کلمات است که با خطوط جدید جدا شده اند؛ هیچ فاصله ای استفاده نشده است.



    حلقه ای که در محتویات یک فایل حلقه می زند

    در اینجا باید در نظر بگیریم که چنین رویکردی، اگر پردازش خط به خط داده ها مورد انتظار باشد، برای فایلی با ساختار پیچیده تر، که خطوط آن ممکن است حاوی چندین کلمه باشد که با فاصله از هم جدا شده اند، کارساز نخواهد بود. حلقه تک تک کلمات را پردازش می کند نه خطوط.

    اگر این چیزی نباشد که اصلاً نیاز دارید چه؟

    جداکننده های میدان

    دلیل ویژگی فوق یک متغیر محیطی ویژه به نام IFS (Internal Field Separator) است که به شما امکان می دهد جداکننده های فیلد را مشخص کنید. به طور پیش فرض، پوسته bash کاراکترهای زیر را به عنوان جداکننده فیلد در نظر می گیرد:

    • فضا
    • کاراکتر برگه
    • کاراکتر فید خط

    اگر bash با هر یک از این کاراکترها در داده ها روبرو شود، فرض می کند که قبل از آن مقدار مستقل بعدی در لیست قرار دارد.

    برای حل این مشکل، می توانید به طور موقت متغیر محیطی IFS را تغییر دهید. در اینجا نحوه انجام آن در یک اسکریپت bash آمده است، با این فرض که فقط به یک خط جدید به عنوان جداکننده فیلد نیاز دارید:

    IFS=$"n"

    هنگامی که این دستور را به اسکریپت bash خود اضافه می کنید، همانطور که انتظار می رود کار می کند، فضاها و تب ها را نادیده می گیرد و فقط کاراکترهای خط جدید را به عنوان جداکننده فیلد در نظر می گیرد.

    #!/bin/bash file="/etc/passwd" IFS=$"n" برای var در $(cat $file) echo "$var" انجام شد

    اگر این اسکریپت اجرا شود، دقیقا همان چیزی را که از آن خواسته شده است، خروجی می دهد و در هر تکرار حلقه، به خط بعدی نوشته شده در فایل دسترسی پیدا می کند.



    پیمایش خط به خط یک فایل در حلقه for

    جداکننده ها نیز می توانند شخصیت های دیگری باشند. به عنوان مثال، در بالا محتویات فایل /etc/passwd را نمایش دادیم. داده های کاربر در خطوط با دو نقطه از هم جدا می شوند. اگر نیاز به پردازش چنین رشته‌هایی در یک حلقه دارید، IFS را می‌توان به شکل زیر پیکربندی کرد:

    عبور از فایل های موجود در یک دایرکتوری

    یکی از رایج ترین موارد استفاده از حلقه های for در اسکریپت های bash، عبور از فایل های واقع در یک فهرست و پردازش آن فایل ها است.

    به عنوان مثال، در اینجا نحوه فهرست کردن فایل ها و پوشه ها آمده است:

    #!/bin/bash برای فایل در /home/likegeeks/* اگر [ -d "$file" ] انجام دهید، سپس "$file یک دایرکتوری است" elif [ -f "$file" ] و سپس echo "$file یک فهرست است" فایل" فی انجام شد

    پوسته bash از حلقه‌ها پشتیبانی می‌کند، که به شما امکان می‌دهد روی دنباله‌ای از مقادیر را تکرار کنید. در اینجا ساختار اصلی چنین حلقه هایی وجود دارد:

    برای var در لیست دستور do انجام شد
    در هر تکرار از حلقه، مقدار بعدی از لیست روی متغیر var نوشته می شود. بنابراین اولین پاس حلقه از اولین مقدار از لیست استفاده می کند. در دوم - دوم و غیره - تا زمانی که حلقه به آخرین عنصر برسد.

    تکرار بر روی مقادیر ساده

    شاید ساده‌ترین مثال حلقه for در اسکریپت‌های bash تکرار بر روی فهرستی از مقادیر ساده باشد:

    #!/bin/bash برای var در اول دوم سوم چهارم پنجم do echo مورد $var انجام شد
    نتایج این اسکریپت در زیر نشان داده شده است. شما به وضوح می بینید که متغیر $var شامل عناصری از لیست به صورت متوالی است. این اتفاق می افتد تا زمانی که چرخه به آخرین آنها برسد.


    ساده برای حلقه

    لطفا توجه داشته باشید که متغیر $var هنگام خروج از حلقه مقدار خود را حفظ می کند، محتویات آن قابل تغییر است و به طور کلی می توانید مانند هر متغیر دیگری با آن کار کنید.

    تکرار بر روی مقادیر پیچیده

    فهرستی که برای مقداردهی اولیه حلقه for استفاده می‌شود، نه تنها می‌تواند شامل رشته‌های ساده متشکل از یک کلمه، بلکه کل عباراتی باشد که حاوی چندین کلمه و علائم نگارشی هستند. به عنوان مثال، ممکن است به شکل زیر باشد:

    #!/bin/bash برای var در اولین "دومین" "سوم" "I’ll do it" echo "This is: $var" انجام شد
    این چیزی است که پس از اینکه این حلقه از لیست عبور می کند اتفاق می افتد. همانطور که می بینید، نتیجه کاملاً قابل انتظار است.


    تکرار بر روی مقادیر پیچیده
    TNW-CUS-FMP - کد تبلیغاتی برای 10٪ تخفیف در خدمات ما، برای فعال سازی ظرف 7 روز در دسترس است.

    راه اندازی یک حلقه با لیستی که از نتایج فرمان بدست می آید

    راه دیگر برای مقداردهی اولیه یک حلقه for این است که به آن لیستی ارسال کنید که نتیجه یک دستور است. در اینجا از جایگزینی دستور برای اجرای آنها و به دست آوردن نتایج کار آنها استفاده می شود.

    #!/bin/bash file="myfile" برای var در $(cat $file) echo "$var" انجام شد
    این مثال از دستور cat استفاده می کند که محتویات یک فایل را می خواند. لیست حاصل از مقادیر به حلقه منتقل می شود و روی صفحه نمایش داده می شود. لطفاً توجه داشته باشید که فایلی که ما به آن دسترسی داریم حاوی لیستی از کلمات است که با خطوط جدید جدا شده اند؛ هیچ فاصله ای استفاده نشده است.


    حلقه ای که در محتویات یک فایل حلقه می زند

    در اینجا باید در نظر بگیریم که چنین رویکردی، اگر پردازش خط به خط داده ها مورد انتظار باشد، برای فایلی با ساختار پیچیده تر، که خطوط آن ممکن است حاوی چندین کلمه باشد که با فاصله از هم جدا شده اند، کارساز نخواهد بود. حلقه تک تک کلمات را پردازش می کند نه خطوط.

    اگر این چیزی نباشد که اصلاً نیاز دارید چه؟

    جداکننده های میدان

    دلیل ویژگی فوق یک متغیر محیطی ویژه به نام IFS (Internal Field Separator) است که به شما امکان می دهد جداکننده های فیلد را مشخص کنید. به طور پیش فرض، پوسته bash کاراکترهای زیر را به عنوان جداکننده فیلد در نظر می گیرد:
    • فضا
    • کاراکتر برگه
    • کاراکتر فید خط
    اگر bash با هر یک از این کاراکترها در داده ها روبرو شود، فرض می کند که قبل از آن مقدار مستقل بعدی در لیست قرار دارد.

    برای حل این مشکل، می توانید به طور موقت متغیر محیطی IFS را تغییر دهید. در اینجا نحوه انجام آن در یک اسکریپت bash آمده است، با این فرض که فقط به یک خط جدید به عنوان جداکننده فیلد نیاز دارید:

    IFS=$"\n"
    هنگامی که این دستور را به اسکریپت bash خود اضافه می کنید، همانطور که انتظار می رود کار می کند، فضاها و تب ها را نادیده می گیرد و فقط کاراکترهای خط جدید را به عنوان جداکننده فیلد در نظر می گیرد.

    #!/bin/bash file="/etc/passwd" IFS=$"\n" برای var در $(cat $file) echo "$var" انجام شد
    اگر این اسکریپت اجرا شود، دقیقا همان چیزی را که از آن خواسته شده است، خروجی می دهد و در هر تکرار حلقه، به خط بعدی نوشته شده در فایل دسترسی پیدا می کند.


    پیمایش خط به خط یک فایل در حلقه for

    جداکننده ها نیز می توانند شخصیت های دیگری باشند. به عنوان مثال، در بالا محتویات فایل /etc/passwd را نمایش دادیم. داده های کاربر در خطوط با دو نقطه از هم جدا می شوند. اگر نیاز به پردازش چنین رشته‌هایی در یک حلقه دارید، IFS را می‌توان به شکل زیر پیکربندی کرد:

    عبور از فایل های موجود در یک دایرکتوری

    یکی از رایج ترین موارد استفاده از حلقه های for در اسکریپت های bash، عبور از فایل های واقع در یک فهرست و پردازش آن فایل ها است.

    به عنوان مثال، در اینجا نحوه فهرست کردن فایل ها و پوشه ها آمده است:

    #!/bin/bash برای فایل در /home/likegeeks/* اگر [ -d "$file" ] انجام دهید، سپس "$file یک دایرکتوری است" elif [ -f "$file" ] و سپس echo "$file یک فهرست است" فایل" فی انجام شد
    اگر مطالب قبلی در این سری مقالات را فهمیده اید، باید ساختار if-then construct و همچنین نحوه تشخیص یک فایل از یک پوشه را بدانید. اگر درک کد بالا برایتان دشوار است، این مطلب را دوباره بخوانید.

    این همان چیزی است که اسکریپت خروجی خواهد داد.


    نمایش محتویات یک پوشه

    توجه کنید که چگونه حلقه را مقداردهی اولیه می کنیم، یعنی علامت "*" در انتهای آدرس پوشه. این نماد را می توان به عنوان یک علامت عام در نظر گرفت به معنای: "همه فایل ها با هر نام". این به شما امکان می دهد تا جایگزینی خودکار نام فایل هایی را که با الگو مطابقت دارند سازماندهی کنید.

    هنگام آزمایش یک شرط در یک دستور if، نام متغیر را در گیومه قرار می دهیم. این کار به این دلیل انجام می شود که نام فایل یا پوشه ممکن است حاوی فاصله باشد.

    سبک C برای حلقه ها

    اگر با زبان برنامه نویسی C آشنایی دارید، سینتکس برای توصیف bash برای حلقه ها ممکن است برای شما عجیب به نظر برسد، زیرا واضح است که شما عادت دارید حلقه ها را به این شکل توصیف کنید:

    برای (i = 0; i< 10; i++) { printf("number is %d\n", i); }
    در اسکریپت‌های bash می‌توانید از حلقه‌ها استفاده کنید، که شرح آن‌ها بسیار شبیه به حلقه‌های سبک C است، اگرچه تفاوت‌هایی نیز وجود دارد. نمودار چرخه با این رویکرد به شکل زیر است:

    برای ((مقدار اولیه متغیر، شرط برای پایان دادن به حلقه، تغییر متغیر))
    در bash می توان اینگونه نوشت:

    برای ((a = 1; a< 10; a++))
    در اینجا یک مثال کار آمده است:

    #!/bin/bash برای ((i=1; i<= 10; i++)) do echo "number is $i" done
    این کد لیستی از اعداد از 1 تا 10 را خروجی می دهد.

    حلقه زدن به سبک C

    حلقه while

    ساختار for تنها راه برای سازماندهی حلقه ها در اسکریپت های bash نیست. همچنین می توانید از حلقه های while در اینجا استفاده کنید. در چنین حلقه‌ای، می‌توانید دستوری برای بررسی یک شرایط خاص و اجرای بدنه حلقه تا زمانی که شرط مورد آزمایش به صفر برمی‌گردد، یا سیگنالی برای تکمیل موفقیت‌آمیز یک عملیات خاص مشخص کنید. وقتی شرط حلقه مقدار غیر صفر را برمی گرداند که به معنای خطا است، حلقه متوقف می شود.

    در اینجا نموداری از سازماندهی حلقه های while آورده شده است
    دستور while check condition
    انجام دادن
    تیم های دیگر
    انجام شده

    بیایید نگاهی به یک نمونه اسکریپت با حلقه ای مانند این بیندازیم:

    #!/bin/bash var1=5 در حالی که [ $var1 -gt 0 ] echo $var1 var1=$[ $var1 - 1 ] انجام شد
    در ورودی حلقه بررسی می شود که آیا متغیر $var1 بزرگتر از صفر است یا خیر. در این صورت بدنه حلقه اجرا می شود که در آن یک عدد از مقدار متغیر کم می شود. این در هر تکرار اتفاق می افتد و قبل از تغییر مقدار متغیر را در کنسول چاپ می کنیم. به محض اینکه $var1 به مقدار 0 رسید، حلقه متوقف می شود.

    نتیجه حلقه while

    اگر متغیر $var1 را تغییر ندهید، این باعث می شود که اسکریپت در یک حلقه بی نهایت قرار گیرد.

    حلقه های تو در تو

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

    #!/bin/bash برای ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
    در زیر آنچه را که این اسکریپت خروجی می دهد آورده شده است. همانطور که می بینید، ابتدا اولین تکرار حلقه بیرونی اجرا می شود، سپس سه تکرار حلقه داخلی، پس از اتمام آن دوباره حلقه بیرونی و سپس دوباره درونی وارد بازی می شود.

    حلقه های تو در تو

    پردازش محتویات فایل

    اغلب از حلقه های تو در تو برای پردازش فایل ها استفاده می شود. بنابراین، حلقه بیرونی روی خطوط فایل تکرار می شود، و حلقه داخلی در حال حاضر با هر خط کار می کند. برای مثال، پردازش فایل /etc/passwd چگونه است:

    #!/bin/bash IFS=$"\n" برای ورود به $(cat /etc/passwd) echo "Values ​​in $entry –" IFS=: برای مقدار در $entry echo "$value" انجام شد انجام شده
    دو حلقه در این اسکریپت وجود دارد. اولین مورد خطوط را با استفاده از کاراکتر خط جدید به عنوان جداکننده طی می کند. داخلی مشغول تجزیه رشته هایی است که فیلدهای آنها با دو نقطه از هم جدا شده اند.

    پردازش داده های فایل

    این رویکرد را می توان در هنگام پردازش فایل های CSV یا هر فایل مشابه، با نوشتن کاراکتر جداکننده در متغیر محیطی IFS در صورت نیاز استفاده کرد.

    مدیریت چرخه

    شاید پس از ورود به حلقه، زمانی که متغیر حلقه به مقدار مشخصی رسید که با شرایط اولیه مشخص شده برای پایان دادن به حلقه مطابقت ندارد، باید آن را متوقف کنید. آیا در چنین شرایطی باید منتظر کامل شدن عادی چرخه بود؟ البته نه، و در چنین مواردی دو دستور زیر مفید خواهند بود:
    • زنگ تفريح
    • ادامه هید

    دستور شکستن

    این دستور به شما اجازه می دهد تا اجرای یک حلقه را قطع کنید. می توان از آن برای هر دو حلقه for و while استفاده کرد:

    #!/bin/bash برای var1 در 1 2 3 4 5 6 7 8 9 10 انجام دهید اگر [ $var1 -eq 5 ] سپس echo fi "Number: $var1" انجام شد
    چنین حلقه ای در شرایط عادی کل لیست مقادیر موجود در لیست را طی می کند. اما در مورد ما، زمانی که متغیر $var1 برابر با 5 باشد، اجرای آن قطع خواهد شد.

    خروج زود هنگام از یک حلقه for

    در اینجا همان چیزی است، اما برای حلقه while:

    #!/bin/bash var1=1 در حالی که [ $var1 -lt 10 ] اگر [ $var1 -eq 5 ] انجام دهید سپس echo fi "تکرار: $var1" var1=$(($var1 + 1)) را انجام دهید
    دستور break که وقتی $var1 به عدد 5 رسید اجرا می شود، حلقه را می شکند. کنسول همان چیزی را که در مثال قبلی نشان داد نمایش می دهد.

    ادامه فرمان

    هنگامی که این دستور در بدنه حلقه مواجه می شود، تکرار فعلی زودتر به پایان می رسد و دستور بعدی بدون خروج از حلقه شروع می شود. بیایید به دستور continue در یک حلقه for نگاه کنیم:

    #!/bin/bash برای ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
    هنگامی که شرط داخل حلقه برآورده شد، یعنی زمانی که $var1 بزرگتر از 5 و کمتر از 10 باشد، پوسته دستور continue را اجرا می کند. این منجر به حذف دستورات باقی مانده در بدنه حلقه و رفتن به تکرار بعدی می شود.

    دستور continue در یک حلقه for

    پردازش خروجی در حال اجرا در یک حلقه

    خروجی داده از یک حلقه را می توان با تغییر مسیر خروجی یا ارسال آن به خط لوله پردازش کرد. این کار با افزودن دستورات پردازش خروجی پس از دستور done انجام می شود.

    به عنوان مثال، به‌جای نشان دادن آنچه در یک حلقه خروجی روی صفحه نمایش داده می‌شود، می‌توانید همه آن‌ها را در یک فایل بنویسید یا آن را در جای دیگری ارسال کنید:

    #!/bin/bash برای ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt اکو "تمام شد."
    پوسته فایل myfile.txt را ایجاد می کند و خروجی دستور for را به آن فایل هدایت می کند. بیایید فایل را باز کنیم و مطمئن شویم که دقیقاً همان چیزی است که ما انتظار داریم.

    تغییر مسیر خروجی حلقه به فایل

    مثال: فایل های اجرایی را جستجو کنید

    بیایید از آنچه قبلاً پوشش داده ایم استفاده کنیم و چیز مفیدی بنویسیم. به عنوان مثال، اگر شما نیاز به یافتن فایل های اجرایی موجود در سیستم دارید، می توانید تمام پوشه های ضبط شده در متغیر محیطی PATH را اسکن کنید. ما در حال حاضر کل زرادخانه ابزارهایی را که برای این کار نیاز داریم در اختیار داریم، فقط باید همه آنها را کنار هم بگذاریم:

    #!/bin/bash.
    این اسکریپت، کوچک و ساده، به ما این امکان را می دهد که لیستی از فایل های اجرایی ذخیره شده در پوشه ها را از PATH دریافت کنیم.

    جستجوی فایل های اجرایی در پوشه ها از متغیر PATH

    نتایج

    امروز در مورد حلقه‌های for و while در اسکریپت‌های bash، نحوه اجرای آنها و نحوه مدیریت آنها صحبت کردیم. اکنون می‌دانید که چگونه رشته‌ها را با جداکننده‌های مختلف در حلقه‌ها پردازش کنید، می‌دانید که چگونه خروجی داده‌ها را در حلقه‌ها به فایل‌ها هدایت کنید، چگونه محتویات دایرکتوری‌ها را مشاهده و تجزیه و تحلیل کنید.

    اگر فرض کنیم که شما توسعه‌دهنده اسکریپت‌های bash هستید که فقط از آنچه در قسمت اول این سری مقالات و در قسمت دوم بیان شده است، می‌دانید، می‌توانید از قبل چیزی مفید بنویسید. قسمت سوم پیش رو است که پس از درک آن، نحوه انتقال پارامترها و سوئیچ های خط فرمان را به اسکریپت های bash و اینکه با همه آن چه باید کرد، در پیش است.

    یکی از قوانین اساسی مدیریت سیستم را می توان به صورت زیر بیان کرد: اگر لازم است یک کار را بارها و بارها انجام دهید، یک اسکریپت بنویسید و بگذارید کار را برای شما انجام دهد. اگر نیاز به انجام چند عمل در یک اسکریپت دارید، باید از آن استفاده کنید چرخه ها. که در گنو باشمی توانید با استفاده از ساختارها حلقه ایجاد کنید برای, در حالی کهو تا زمان.

    اگر تا به حال به برنامه نویسی علاقه داشته اید، به احتمال زیاد از قبل با این ساختارها آشنا هستید. اگر شما هم مثل من در حال مطالعه هستید ضربه شدیدبدون هیچ گونه تجربه برنامه نویسی، استفاده از حلقه ها ممکن است به اندازه کافی واضح نباشد. بیایید با تعریف تفاوت بین انواع مختلف حلقه ها شروع کنیم و سپس به مثال ها برویم.

    چرخه برایبرای تکرار اقدامات تا زمانی که همه آنها کامل شوند طراحی شده است. به عنوان مثال، تصور کنید که یک کاتالوگ از تصاویر دارید و باید آنها را از یک فرمت به فرمت دیگر تبدیل کنید. می توانید از حلقه استفاده کنید برایهمراه با برنامه تبدیلاز بسته ImageMagick(یا برنامه دیگری)، به عنوان مثال، برای تبدیل تصاویر از فرمت JPEG به فرمت PNG. یا، برای مثال، ممکن است لازم باشد بسیاری از فایل های صوتی را از آن تبدیل کنید MP3 V OGG Vorbis.

    چرخه در حالی کهبرای تکرار اعمال استفاده می شود خدا حافظاجرا می شود (است درست است، واقعی) برخی شرایط چرخه تا زمانکمی متفاوت عمل می کند: یک عمل را انجام می دهد تا زمانتا زمانی که شرط محقق شود. بنابراین، برای مثال، می توانید یک شمارنده داشته باشید و یک عمل انجام دهید تا زمان، تا زمانی که مقدار آن به 10 برسد. بیایید با استفاده از مثال ها به این موضوع با جزئیات بیشتری نگاه کنیم.

    بیایید با چرخه شروع کنیم برای. فرمت آن این است:

    برای i در $(command); دستور $i را انجام دهید. انجام شده

    اگر از حلقه استفاده می کنید برایدر اسکریپت، بهتر است آن را به این صورت قالب بندی کنید:

    #!/bin/bash برای i در $(command); دستور $i انجام شود

    بنابراین، به عنوان مثال، اگر شما نیاز به تهیه نسخه پشتیبان از تمام فایل های HTML موجود در یک دایرکتوری دارید، می توانید از دستور زیر استفاده کنید:

    برای i در $(ls *html); انجام cp $i $i.bak; انجام شده

    یک متغیر محلی در اینجا ایجاد می شود $i، دستور اجرا می شود ls *html، که نتایج آن داده ای خواهد بود که مقدار متغیر را مقدار دهی اولیه می کند $iدر هر تکرار حلقه (در مثال ما این لیستی از فایل‌های بازگردانده شده توسط دستور است ls، یکی برای هر تکرار). سپس دستور اجرا می شود cp، که یک متغیر از بین پارامترها به آن ارسال می شود $i.

    ممکن است برخی بپرسند که آیا استفاده از نامه ضروری است یا خیر "من"به عنوان یک نام متغیر؟ خیر شما می توانید از هر صحیح استفاده کنید ضربه شدیدنام متغیر البته بهتر است از نام متغیرهای معنی دار تری در اسکریپت های خود استفاده کنید ورودی $یا $html.

    من یک مثال بسیار کوتاه و ساده از استفاده از حلقه زدم برای. به جای دستوری که در یک بلوک اجرا می شود انجام دادن،استفاده کنید اکوبرای دیدن پارامترهای ارسال شده به آن. این یک تمرین بسیار مفید در مرحله آزمایش اسکریپت ها است و همچنین راه خوبی برای کمک به درک جزئیات بیشتر کار است. برای.

    در حالی که و تا زمانی

    اجازه دهید اکنون ساختارها را در نظر بگیریم در حالی کهو تا زمان. از شرط bash نیز کمی استفاده خواهیم کرد. در مثال ما از آنها برای تعیین اینکه آیا مقدار یک متغیر بزرگتر است یا کمتر از عدد X استفاده خواهیم کرد. آیا فایل وجود دارد و یک دایرکتوری است. همچنین می توانید از عبارات شرطی برای تعیین اینکه آیا یک فایل قابل خواندن است یا اینکه آیا یک فایل دارای بیت GID در مجوزهایش است یا خیر، استفاده کنید.

    بیایید یک چیز ساده را امتحان کنیم، مانند ایجاد چند فایل خالی. بعید است که این در زندگی برای شما مفید باشد، اما به عنوان مثال، همین است.

    #!/bin/bash i=0 در حالی که [ $i -lt 22 ] $i i=$[$i+1] انجام شد را لمس کنید

    این اسکریپت 22 فایل با نام های 0 تا 21 ایجاد می کند. حلقه تا زمانی که اجرا می شود خدا حافظمقدار متغیر $iکمتر ( -آن) 22.

    حالا بیایید با استفاده از یک حلقه از شر فایل های ایجاد شده خلاص شویم تا زمان:

    #!/bin/bash i=0 تا زمانی که [ $i -eq 22 ] rm $i i=$[$i+1] انجام شود

    در اینجا ما جایگزین کرده ایم در حالی کهبر تا زمان، و در عبارت شرطی جایگزین شدند "کمتر" (-آن) بر "برابر" (معادله). بنابراین، اسکریپت ما تا زمانی که مقدار کار می کند $iبه 22 نخواهد رسید و در عوض دست زدن بهما با استفاده از rmبرای حذف فایل ها به جای ایجاد آنها ساده است، اینطور نیست؟

    در این سخنرانی در ادامه با آن آشنا می شویم ضربه شدید. من می خواهم به شما یادآوری کنم که ما در حال بررسی آن عناصر هستیم ضربه شدید، که به ما در درک اسکریپت های سیستم عامل کمک می کند. چنین عناصری قطعا حلقه ها و توابع هستند. اگر کسی برنامه نویسی خوانده باشد، در درک این سوالات هیچ مشکلی وجود نخواهد داشت.

    برای حلقه

    چرخه برای V ضربه شدیددو نوع دارد بیایید ابتدا به نسخه کلاسیک نگاه کنیم برای. نمای کلی به شرح زیر است:

    بین عناصر برایو که دریک متغیر تنظیم می شود که به نوبه خود مقداری را از دنباله مقادیر مشخص شده بین آن می گیرد که درو انجام دادن. بین انجام دادنو انجام شدهدستوراتی وجود دارد که هر بار که یک متغیر مقدار خود را تغییر می دهد، اجرا می شود. حلقه زمانی متوقف می شود که متغیر آخرین مقدار را از دنباله بگیرد. مقادیر در دنباله با فاصله از هم جدا می شوند.

    در اینجا یک مثال عملی آورده شده است:

    توالی مقادیر را می توان به روش های مختلفی مشخص کرد. به طور واضح - مانند مثال بالا، یا استفاده از متغیرهای دیگر، یا استفاده از دستورات خاص. بیایید به چند نمونه نگاه کنیم. از آنجایی که مقادیر به تفکیک فاصله مشخص می شوند، چنین مقادیری می تواند هر متغیری باشد که شامل رشته ای با فاصله باشد:

    نتیجه مانند مثال اول خواهد بود.

    در صورت نیاز به تعیین دنباله ای از اعداد، می توانید از دستور استفاده کنید دنبالهو مکانیسم جایگزینی تیم دنبالهدنباله ای از مقادیر عددی را به صفحه نمایش برمی گرداند. نحو ساده است و از مثال زیر مشخص خواهد شد:

    نتیجه:

    به نوع دوم برگردیم برای. اغلب در اسکریپت ها می توانید نوع به اصطلاح C-like را پیدا کنید برای، که برای حلقه های مبتنی بر عدد استفاده می شود. بیایید به یک مثال نگاه کنیم:

    حلقه تا زمانی اجرا می شود که شرط مورد آزمایش در عبارت درست باشد. به محض اینکه عبارت false برگرداند، اجرای حلقه متوقف می شود.

    مثال عملی:

    #!/bin/bash
    i=1
    در حالی که [$i -lt 7 ]
    انجام دادن
    پژواک $i
    اجازه دهید i=i+1
    انجام شده

    در مثال ما، آن متغیر را بررسی می کنیم منکوچکتر از (-lt) عدد 7 است و اگر چنین است، مقدار متغیر روی صفحه نمایش داده می شود. اصطلاح اجازه دهید i=i+1، متغیر را یک بار افزایش می دهد، دوباره بررسی می کند و غیره. let به مفسر می گوید که آرگومان ها باید به عنوان مقادیر عددی شناسایی شوند. این خط می تواند به صورت نوشته شود اجازه دهید من ++(نوعی مانند c). هنگامی که یک عدد بیش از یک افزایش می یابد، می توان آن را به صورت زیر نوشت: اجازه دهید i+=2- در این مورد منبا افزایش 2 افزایش می یابد. گزینه دیگر برای افزایش یک متغیر استفاده از ماشین حساب داخلی است (فقط با اعداد صحیح کار می کند). از طریق دو براکت می توان به ماشین حساب دسترسی داشت: i=$(($i+1))یا از طریق مربع ها: i=$[$i+1]همچنین می توانید از ماشین حساب در خط فرمان استفاده کنید:

    شما باید مراقب حلقه ها باشید تا در نهایت به یک حلقه بی پایان نرسید. به هر حال، برای اشکال زدایی ضربه شدیداسکریپت هایی که می توانید خط اول را به آنها تغییر دهید #!/bin/bash -xیا اسکریپت را با دستور اجرا کنید bash -x:

    igor@ubuntu:~/linux$ bash -x ./testfor.sh
    + i=1
    + '[' 1 -gt 5 ']'
    + echo i=1
    i=1
    + اجازه دهید i=i+1
    + '[' 2 -gt 5 ']'
    + echo i=2
    i=2
    + اجازه دهید i=i+1
    + '[' 3 -gt 5 ']'
    + echo i=3
    i=3
    + اجازه دهید i=i+1
    + '[' 4 -gt 5 ']'
    + echo i=4
    i=4
    + اجازه دهید i=i+1
    + '[' 5 -gt 5 ']'
    + echo i=5
    i=5
    + اجازه دهید i=i+1
    + '[' 6 -gt 5 ']'

    حتماً نوشتن اسکریپت های کوچک را تمرین کنید تا درک خود را از نحوه عملکرد حلقه ها تقویت کنید ضربه شدید.

    توابع در bash

    توابع در استفاده می شود ضربه شدیدخیلی عریض. توابع به دو صورت توصیف می شوند: با یک کلمه کلیدی تابع، و بدون آن.

    راه اول:

    تابع function_name
    {
    بدن عملکرد
    }

    راه دوم:

    function_name()
    {
    بدن عملکرد
    }

    یک تابع در هر جایی از اسکریپت با نام فراخوانی می شود، اما تنها پس از توصیف خود تابع. توابع همچنین می توانند پارامترهایی را ارسال کنند که با فاصله پس از فراخوانی تابع (نام) مشخص می شوند. بیایید به یک نمونه اسکریپت نگاه کنیم ضربه شدید:

    #!/bin/bash
    پرایمر عملکردی
    {
    اگر [$# -ne 0 ]
    سپس
    محلی a=1
    echo "تعداد پارامترهای ارسال شده - $#"
    برای من در $@
    انجام دادن
    echo "$a-امین پارامتر $i است"
    اجازه دهید ++
    انجام شده
    بازگشت 0
    دیگر
    echo "پارامترها تصویب نشدند"
    بازگشت 1
    فی
    }
    echo "فراخوانی یک تابع با پارامترها:"
    آغازگر a b c
    اکو $؟
    echo "فراخوانی یک تابع بدون پارامتر:"
    آغازگر
    اکو $؟

    در این مثال، تابعی به نام آغازگر. فراخوانی یک تابع با پارامترها: آغازگر a b cو بدون پارامتر: آغازگر. در بدنه تابع، تمام ساختارها باید برای شما آشنا باشند، به استثنای $# , $iو $@ .$# — تعداد پارامترهای ارسال شده به تابع را برمی گرداند. در مثال ما این یک عدد خواهد بود 3 .$@ تمام پارامترها را در یک خط برمی گرداند. در مثال آن خواهد بود a b c. و از طریق $1 , $2 , $3 و غیره. شما می توانید به هر پارامتر به صورت جداگانه دسترسی داشته باشید. $? - حاوی کد اجرای آخرین دستور است. در مثال ما، کد اجرای تابع.

    این تابع همچنین می تواند یک مقدار عددی را از طریق یک کلمه کلیدی برگرداند برگشت. معمولاً اگر عملکرد بدون خطا اجرا شود 0 یا اگر مشکلی پیش بیاید مقدار غیر صفر را برمی‌گردانند. در مثال، اگر تابعی با پارامتر فراخوانی شود، مقدار 0 برگردانده می شود و اگر تابع بدون پارامتر فراخوانی شده باشد، کد 1 برگردانده می شود.

    همه چیز در مورد ارسال پارامترها به یک تابع دقیقاً برای یک اسکریپت کار می کند. شما همچنین می توانید پارامترها را به اسکریپت ارسال کنید و آنها را به همان روش با استفاده از دستکاری کنید $#، $@، $N. از همان دسته گزینه است - $0 - که نام دستوری را که اسکریپت را راه اندازی کرده است برمی گرداند. اگر اسکریپت با دستور اجرا می شد ./script.sh، سپس اکو $0 مقدار را برمی گرداند ./script.sh، و اگر به دستور باشد /home/igor/linux/script.sh، سپس مقدار برگردانده می شود /home/igor/linux/script.sh.