مقدمه‌ای بر تکمیل قابل برنامه‌ریزی

پیوست ‎J‎- مقدمه‌ای بر تکمیل قابل برنامه‌ریزی

ویژگی تکمیل قابل برنامه‌ریزی در Bash، تایپ نمودن بخشی از یک فرمان و سپس فشردن کلید ‎[Tab]‎ برای تکمیل خودکار رشته فرمان را ممکن می‌سازد. ‎[1]‎ اگر چند نمونه تکمیل محتمل باشد، آنوقت ‎[Tab]‎ تمام آنها را لیست می‌کند. اجازه بدهید ببینیم چگونه کار می‌کند.

bash$ xtra[Tab]
 xtraceroute       xtrapin           xtrapproto
 xtraceroute.real  xtrapinfo         xtrapreset
 xtrapchar         xtrapout          xtrapstats

bash$ xtrac[Tab]
xtraceroute       xtraceroute.real

bash$ xtraceroute.r[Tab]
xtraceroute.real

تکمیل‌ کردن Tab برای متغیرها و نام مسیرها نیز کار می‌کند.

bash$ echo $BASH[Tab]
 $BASH                 $BASH_COMPLETION      $BASH_SUBSHELL
 $BASH_ARGC            $BASH_COMPLETION_DIR  $BASH_VERSINFO
 $BASH_ARGV            $BASH_LINENO          $BASH_VERSION
 $BASH_COMMAND         $BASH_SOURCE

bash$ echo /usr/local/[Tab]
 bin/     etc/     include/ libexec/ sbin/    src/     
 doc/     games/   lib/     man/     share/

فرمان‌های داخلی complete و compgen در Bash تشخیص پارامترهای نیمه‌کامل و گزینه‌ فرمان‌ها را برای ‎tab completion‎ امکان‌پذیر می‌کند. در یک حالت بسیار ساده، ما می‌توانیم complete را از خط فرمان برای تعیین یک لیست کوتاه پارامترهای قابل قبول به کار ببریم.

bash$ touch sample_command
bash$ touch file1.txt file2.txt file2.doc file30.txt file4.zzz
bash$ chmod +x sample_command
bash$ complete -f -X '!*.txt' sample_command

bash$ ./sample[Tab][Tab][Tab]
sample_command
file1.txt   file2.txt   file30.txt

گزینه ‎-f‎ با complete نام فایل‌ها را، و گزینه ‎-X‎ الگوی فیلتر را مشخص می‌کند.

برای هر مورد پیچیده‌تر، ما می‌توانیم اسکریپتی بنویسیم که لیستی از پارامترهای قابل قبول خط فرمان را مشخص نماید. فرمان داخلی compgen لیستی از شناسه‌ها را برای تولید انطباق‌های تکمیل بسط می‌دهد.

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

مثال ‎J-1‎. اسکریپت تکمیل برای ‎UseGetOpt.sh‎

# 
#  تکمیل پارامتر

_UseGetOpt-2 ()   # مطابق قرارداد، نام تابع با یک
{                 #+           خط زیر شروع می‌شود.
  local cur
  #               اشاره کننده به کلمه تکمیل جاری.
  # طبق قرارداد، cur نامیده شده، اما این به طور اکید ضرورت ندارد.

  COMPREPLY=()    #    متغیر آرایه تکمیل‌های محتمل را ذخیره می‌کند.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
                               --file --log --test --help --' -- $cur ) );;
# تولید انطباق‌های تکمیل و بار کردن آن‌ها در آرایه ‎$COMPREPLY‎
#    می‌شود موارد بیشتری در اینجا اضافه نمود.
# 
# 
  esac

  return 0
}

complete -F _UseGetOpt-2 -o filenames ./UseGetOpt-2.sh
#   تابع ‎_UseGetOpt-2‎ را احضار می‌کند.

اکنون بیایید آن را امتحان کنیم.

bash$ source UseGetOpt-2.sh
bash$ ./UseGetOpt-2.sh -[Tab]
--         --aoption  --debug    --file     --help     --log     --test
 -a         -d         -f         -h         -l         -t

bash$ ./UseGetOpt-2.sh --[Tab]
--         --aoption  --debug    --file     --help     --log     --test

ما به وسیله source کردن «اسکریپت تکمیل» شروع می‌کنیم. این کار موجب برقراری پارامترهای خط فرمان می‌گردد. ‎[2]‎

در اولین نمونه، فشردن ‎[Tab]‎ بعد از یک خط تیره منفرد، خروجی تمام پارامترهای ممکن دارای یک یا چند خط تیره مقدم است. زدن ‎[Tab]‎ بعد از دو خط تیره تمام پارامترهای ممکن دارای دو یا چند خط تیره مقدم را ارایه می‌کند.

حال، فقط هدف پریدن از میان حلقه‌های شعله‌ور برای فعال کردن تکمیل tab خط فرمان چیست؟ این کار در ضربه کلیدها صرفه جویی می‌کند. ‎[3]‎

--

منابع:

پروژه تکمیل قابل برنامه‌ریزی Bash

مقاله ‎Mitch Frazier‎ در ‎Linux Journal‎ با عنوان ‎More on Using the Bash Complete Command‎

مقاله بسیار خوب دوقسمتی ‎Steve‎، «مقدمه‌ای بر ‎Bash Completion‎»: بخش نخست و بخش دوم

یادداشت‌ها

[1]

البته، این فقط از خط فرمان کار می‌کند، و نه در داخل یک اسکریپت.

[2]

به طور عادی فایل‌های تکمیل پارامتر پیش‌فرض یا در دایرکتوری ‎/etc/profile.d‎ یا در ‎/etc/bash_completion‎ قرار دارند. اینها موقع راه‌اندازی سیستم به طور خودکار بارگذاری می‌شوند. بنابراین، بعد از نوشتن یک اسکریپت تکمیل سودمند، ممکن است مایل باشید آن را (البته به عنوان root) به یکی از این دایرکتوری‌ها انتقال بدهید.

[3]

به طور گسترده‌ای اثبات گردیده است که برنامه‌نویسان مایل هستند، برای صرفه‌جویی ده دقیقه زحمت «غیر ضروری»، ساعت‌های طولانی تلاش به عمل آورند. این کار بهینه‌سازی نامیده می‌شود.