آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

پرسش و پاسخ شماره ۸۴

پرسش و پاسخ شماره ۸۴

چگونه یک رشته (یا عدد بلند، یا عدد منفی) را در نتیجه یک تابع برگشت بدهم؟ return فقط استفاده از اعداد 0 تا 255 را اجازه می‌دهد.

توابع در Bash (همچنین سایر پوسته‌های هم خانواده شل Bourne) مانند فرمانها کار می‌کنند: یعنی، آنها فقط یک وضعیت خروج برگشت می‌دهند که منحصر به اعداد صحیح از 0 تا 255 است. این به منظور استفاده در علامت‌دهی خطاها می‌باشد، نه برای بازگرداندن نتایج محاسبات یا سایر داده‌ها.

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

  • ممکن است تابعی داشته باشید که داده را در stdout بنویسد، و سپس فراخوان کننده stdout را بگیرد.
    •   foo() {
           echo "this is my data"
        }
        x=$(foo)
        echo "foo returned '$x'"

    یک اشکال این روش آنست که تابع در یک پوسته فرعی اجرا می‌شود، و این به معنای آنست که هر تخصیص متغیر و غیره که در تابع انجام شده بر محیط فراخوان کننده تأثیر نمی‌گذارد (و به واسطه یک ‎fork()‎ متحمل خسارت سرعت هم می‌گردد). این مطلب بسته به احتیاجات برنامه و تابع شما، می‌تواند مشکلی باشد یا نباشد. یک اشکال دیگر آنست که هر آنچه توسط تابع foo چاپ می‌شود، اخذ می‌گردد و در متغیر قرار داده می‌شود. اگر تابع foo همچنین چیزهایی را که قرار نیست یک مقدار برگشتی باشند، می‌نویسد، این مطلب به مشکلاتی منجر می‌شود. برای جداکردن اعلانهای کاربر و(یا) پیغام خطاها از داده‌های برگشتی، آنها را به stderr که توسط فراخواننده اخذ نمی‌شود تغییر مسیر بدهید.

  •  foo() {
        echo "running foo()..."  >&2  #می‌فرستد stderr اعلانهای کاربر و خطاها را به 
        echo "this is my data"       # این مقدار پایین به متغیر اختصاص داده می‌شود
     }
     x=$(foo)                        # را چاپ می‌کند running foo()...
     echo "foo returned '$x'"        # را چاپ می‌کند foo returned 'this is my data'
  • می‌توانید داده را به متغیرهای سراسری تخصیص بدهید، و سپس در فرا خوان کننده به آن متغیرها ارجاع بدهید.
    •   foo() {
           return="this is my data"
        }
        foo
        echo "foo returned '$return'"

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

  • تابع شما می‌تواند داده‌اش را در یک فایل بنویسد، در جایی که فراخواننده بتواند آن را بخواند.
    •   foo() {
           echo "this is my data" > "$1"
        }
        # !این کد استواری برای مدیریت فایلهای موقتی نیست
        tmpfile=$(mktemp)   # GNU/Linux
        foo "$tmpfile"
        echo "foo returned '$(<"$tmpfile")'"
        rm "$tmpfile"
        #  کرده بودیم trap اگر این برنامه واقعی بود، بررسی خطا و  
      • اشکالات این شیوه نیز باید واضح باشد: شما نیاز به مدیریت فایل موقت دارید، که همواره ناجور است، باید یک دایرکتوری قابل نوشتن در جایی، و فضای کافی برای نگهداری داده‌ها در آن وجود داشته باشد، و غیره. از جنبه مثبت، صرف نظر از اینکه تابع در پوسته فرعی اجرا می‌شود، کار خواهد کرد.

    برای اطلاعات بیشتر در مورد مدیریت فایلهای موقت از درون اسکریپت پوسته، پرسش و پاسخ شماره 62 را ببینید. برای trapها، صفحه SignalTrap را ملاحظه کنید.


CategoryShell

پرسش و پاسخ 84 (آخرین ویرایش ‎2012-10-16 17:56:51‎ توسط GreyCat)