কিভাবে স্বয়ংক্রিয় সম্পূর্ণ সঙ্গে স্ক্রিপ্ট তৈরি করবেন?


118

আমি যখন প্রোগ্রামটি ব্যবহার করি svnএবং আমি জিনোম টার্মিনাল টাইপ করি:

svn upd

এবং Tabএটিতে স্বয়ংক্রিয়ভাবে পূর্ণ হিট করুন:

svn update

আমার কাস্টম বাশ স্ক্রিপ্টে কি এমন কিছু করা সম্ভব?


"বাশ স্ক্রিপ্ট" ব্যাখ্যা করুন, স্ক্রিপ্ট সম্পাদনা করার সময় আপনার অর্থ? কি আপনি এটি দিয়ে কি করতে চান?
ব্রুনো পেরেইরা

3
কনসোলে স্ক্রিপ্টটি ব্যবহার করার সময়
ইউএডাপ্টার

আপনার পরিপূর্ণতা কোথায় রাখবেন সেই জায়গার জন্য, এই প্রশ্নটি এবং সেখানে গৃহীত উত্তরের জন্য মন্তব্যগুলি দেখুন।
জার্নো

উত্তর:


43

আপনি প্রোগ্রামেবল সম্পূর্ণতা ব্যবহার করতে পারেন । কিছু উদাহরণ দেখুন /etc/bash_completionএবং /etc/bash_completion.d/*জন্য দেখুন ।


130
প্রশ্নটির সাথে সরাসরি সম্পর্কিত একটি সাধারণ উদাহরণ অন্তর্ভুক্ত করবেন কীভাবে?
মাউন্টেনএক্স

2
উবুন্টু 16 জন্য প্রকৃত স্ক্রিপ্ট মধ্যে অবস্থিত হয়/usr/share/bash-completion/completions/<program>
পিটার

16
তবে, উদাহরণগুলিতে উত্তরের অন্তর্ভুক্ত করা উচিত, কোনও লিঙ্কে নয়।
বিলেণোহ

2
আমি বিশ্বাস করি যে এই প্ল্যাটফর্মটি সম্পূর্ণ ডকুমেন্টেশনের আরও কার্যকর বিকল্প বলে মনে করা হচ্ছে যা একটি সাধারণ গুগল অনুসন্ধানের সাথে পাওয়া যেতে পারে। একটি ডকুমেন্টেশন লিঙ্ক ডাম্পিং এর সাহায্য করে না। অ্যাঙ্করযুক্ত লিঙ্কটি অবশ্যই খুব বেশি পার্থক্য করে না।
টিমুয়িন

4
The provided link has that already- এটা আজ হতে পারে, কিন্তু এটি আগামীকাল নাও হতে পারে। বা পরের বছর। বা এক দশকে। ডকুমেন্টেশন সম্পর্কে আপনি যা কিছু পরামর্শ দিতে পারেন তা এখনও প্রাসঙ্গিক, স্ট্যাক ওভারফ্লো এই কারণগুলির জন্য লিংক-উত্তরগুলিকে নিরুৎসাহিত করে।
লিয়াম ডসন

204

আমি ছয় মাস দেরি করছি কিন্তু আমি একই জিনিসটি খুঁজছিলাম এবং এটি পেয়েছি:

আপনাকে একটি নতুন ফাইল তৈরি করতে হবে:

/etc/bash_completion.d/foo

একটি স্থিতিশীল স্ব-সমাপ্তির জন্য ( --help/ --verboseউদাহরণস্বরূপ) এটি যুক্ত করুন:

_foo() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help --verbose --version"

    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _foo foo
  • COMP_WORDS বর্তমান কমান্ড লাইনের সমস্ত স্বতন্ত্র শব্দযুক্ত একটি অ্যারে।
  • COMP_CWORD বর্তমান কার্সার অবস্থান সম্বলিত শব্দের একটি সূচক।
  • COMPREPLY একটি অ্যারে ভেরিয়েবল যা থেকে বাশ সম্ভাব্য কমপ্লিটগুলি পড়ে।

আর compgenকমান্ড ফেরৎ থেকে উপাদানগুলি অ্যারে --help, --verboseএবং --versionবর্তমান শব্দ মিলে "${cur}":

compgen -W "--help --verbose --version" -- "<userinput>"

সূত্র: http://www.debian-administration.org/articles/316


27
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত! এটি একটি সম্পূর্ণ উদাহরণ।
ভিক্টর শ্রদার

5
টিপ: যদি কেউ শব্দটির শুরু না হওয়া শর্তগুলির জন্য পরামর্শ চান -এবং লক্ষ্য শব্দটি লেখা শুরু না করে সেগুলি দেখায়, কেবল if [...] thenএবং fiলাইনগুলি সরিয়ে দিন ।
সিড্রিক রেইচেনবাচ

1
এটি হ'ল সঠিক উত্তর যা আমি কয়েক ঘন্টা সন্ধান করেছি এবং এটি কিছু জটিল ডকুমেন্টেশনে ডুবে গেছে যা কেবল কখনও উল্লেখ করেনি যে ফাইলটি রাখা উচিত /etc/bash_completion.d/। আমি কেবল এখানে এসেছি কারণ আমি কোথাও একটি উত্তর পোস্ট করতে চেয়েছিলাম, তবে এটি প্রমাণিত হয়েছে যে কেউ তিন বছর আগে সমস্ত পাশে ছিল :) পরিষ্কার, সংক্ষিপ্ত এবং সম্পূর্ণ উদাহরণ, আপনাকে ধন্যবাদ!
স্টেইন শ্যাট


34

ব্যাশের সম্পূর্ণকরণগুলি সমস্ত সঞ্চিত /etc/bash_completion.d/। সুতরাং আপনি যদি ব্যাশ_কম্প্লেশন দিয়ে সফ্টওয়্যার তৈরি করছেন তবে সেই ডিরেক্টরিতে সফ্টওয়্যারটির নাম সহ একটি ফাইল ডাব / মেক ইনস্টল করা সার্থক হবে। এখানে Rsync এর জন্য বাশ সম্পূর্ণ করার স্ক্রিপ্টের একটি উদাহরণ রয়েছে:

# bash completion for rsync

have rsync &&
_rsync()
{
    # TODO: _split_longopt

    local cur prev shell i userhost path   

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    _expand || return 0

    case "$prev" in
    --@(config|password-file|include-from|exclude-from))
        _filedir
        return 0
        ;;
    -@(T|-temp-dir|-compare-dest))
        _filedir -d
        return 0
        ;;
    -@(e|-rsh))
        COMPREPLY=( $( compgen -W 'rsh ssh' -- "$cur" ) )
        return 0
        ;;
    esac

    case "$cur" in
    -*)
        COMPREPLY=( $( compgen -W '-v -q  -c -a -r -R -b -u -l -L -H \
            -p -o -g -D -t -S -n -W -x -B -e -C -I -T -P \
            -z -h -4 -6 --verbose --quiet --checksum \
            --archive --recursive --relative --backup \
            --backup-dir --suffix= --update --links \
            --copy-links --copy-unsafe-links --safe-links \
            --hard-links --perms --owner --group --devices\
            --times --sparse --dry-run --whole-file \
            --no-whole-file --one-file-system \
            --block-size= --rsh= --rsync-path= \
            --cvs-exclude --existing --ignore-existing \
            --delete --delete-excluded --delete-after \
            --ignore-errors --max-delete= --partial \
            --force --numeric-ids --timeout= \
            --ignore-times --size-only --modify-window= \
            --temp-dir= --compare-dest= --compress \
            --exclude= --exclude-from= --include= \
            --include-from= --version --daemon --no-detach\
            --address= --config= --port= --blocking-io \
            --no-blocking-io --stats --progress \
            --log-format= --password-file= --bwlimit= \
            --write-batch= --read-batch= --help' -- "$cur" ))
        ;;
    *:*)
        # find which remote shell is used
        shell=ssh
        for (( i=1; i < COMP_CWORD; i++ )); do
            if [[ "${COMP_WORDS[i]}" == -@(e|-rsh) ]]; then
                shell=${COMP_WORDS[i+1]}
                break
            fi
        done
        if [[ "$shell" == ssh ]]; then
            # remove backslash escape from :
            cur=${cur/\\:/:}
            userhost=${cur%%?(\\):*}
            path=${cur#*:}
            # unescape spaces
            path=${path//\\\\\\\\ / }
            if [ -z "$path" ]; then
                # default to home dir of specified
                # user on remote host
                path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
            fi
            # escape spaces; remove executables, aliases, pipes
            # and sockets; add space at end of file names
            COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \
                command ls -aF1d "$path*" 2>/dev/null | \
                sed -e 's/ /\\\\\\\ /g' -e 's/[*@|=]$//g' \
                -e 's/[^\/]$/& /g' ) )
        fi
        ;;
    *)  
        _known_hosts_real -c -a "$cur"
        _filedir
        ;;
    esac

    return 0
} &&
complete -F _rsync $nospace $filenames rsync

# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh

আপনার প্রোগ্রামটির সান্নিধ্যের সাথে মিল রয়েছে এমন কোনও ব্যাশ সমাপ্তির ফাইলগুলির পর্যালোচনা করা সার্থক হবে। সবচেয়ে সহজ উদাহরণগুলির মধ্যে একটি rrdtoolফাইল।


2
অন্যান্য স্থান থেকে লোড করার জন্য আমরা কী পরিপূর্ণতা কনফিগার করতে পারি? অর্থাৎ। ~ / .local
ক্রিস

1
হ্যাঁ, আপনি এই মত একটি ফাইল যেখানেই থাকুন না কেন আপনি চান করা এবং তারপর লাগাতে পারেন source ~/.local/mycrazycompletionআপনার~/.bashrc
স্টেফানো মধ্যে Palazzo


আজকাল বেশিরভাগ pkg-cপরিপূর্ণতা কমান্ড onfig --variable = পরিপূর্ণতা বাশ-সমাপ্তি দ্বারা প্রদত্ত ডিরেক্টরিতে অবস্থিত that এবং সেই ডিরেক্টরিটি উপরে লিঙ্কযুক্ত বাশ কমপ্লিটেশন এফএকিউ দ্বারা প্রদত্ত সুপারিশ।
জার্নো

33

এখানে একটি সম্পূর্ণ টিউটোরিয়াল।

অ্যাডমিন.শ নামে পরিচিত স্ক্রিপ্টের একটি উদাহরণ দেওয়া যাক যাতে আপনি স্বতঃপূরণ কাজ করতে চান।

#!/bin/bash

while [ $# -gt 0 ]; do
  arg=$1
  case $arg in
    option_1)
     # do_option_1
    ;;
    option_2)
     # do_option_1
    ;;
    shortlist)
      echo option_1 option_2 shortlist
    ;;
    *)
     echo Wrong option
    ;;
  esac
  shift
done

নোট বিকল্প শর্টলিস্ট। এই বিকল্পটির সাথে কল করার স্ক্রিপ্ট এই স্ক্রিপ্টের জন্য সমস্ত সম্ভাব্য বিকল্প মুদ্রণ করবে।

এবং এখানে আপনার স্বয়ংসম্পূর্ণ স্ক্রিপ্ট রয়েছে:

_script()
{
  _script_commands=$(/path/to/your/script.sh shortlist)

  local cur
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  COMPREPLY=( $(compgen -W "${_script_commands}" -- ${cur}) )

  return 0
}
complete -o nospace -F _script ./admin.sh

নোট করুন যে সম্পূর্ণ যুক্তিটি শেষ করতে হবে সেই স্ক্রিপ্টটির নাম যা আপনি স্বতঃপূরণ যোগ করতে চান। আপনাকে যা করতে হবে তা হ'ল বাশার্কে আপনার স্ব-পরিপূর্ণ স্ক্রিপ্ট যুক্ত করা

source /path/to/your/autocomplete.sh

অথবা /etc/bash.completion.d এ এটি অনুলিপি করুন


1
কি prevজন্য পরিবর্তনশীল? আপনি এটি ব্যবহার করে বলে মনে হয় না।
dimo414

@ ডিমো 414 মনে হচ্ছে, আমি সেই পরিবর্তনশীলটিকে সরিয়ে দিয়েছি
2:19

-o nospaceবিকল্পটি কী করে ?
অ্যান্ড্রু লামার

11

আপনি যা চান তা যদি একটি সাধারণ শব্দ ভিত্তিক স্বতঃ-সমাপ্তি হয় (সুতরাং কোনও সাবকম্যান্ড সমাপ্তি বা কোনও কিছুই নেই), completeকমান্ডের একটি -Wবিকল্প রয়েছে যা ঠিক কাজটি করে।

উদাহরণস্বরূপ, আমার .bashrcকাছে জুপিটার নামে একটি প্রোগ্রামটি স্বতঃপূরণ করতে আমার নিচের লাইনগুলি রয়েছে :

# gleaned from `jupyter --help`
_jupyter_options='console qtconsole notebook' # shortened for this answer
complete -W "${_jupyter_options}" 'jupyter'

এখন jupyter <TAB> <TAB>আমার জন্য স্বয়ংক্রিয়ভাবে পূর্ণ।

ডক্স gnu.org এ সহায়ক।

IFSভেরিয়েবলটি সঠিকভাবে সেট করা হচ্ছে বলে মনে হচ্ছে তবে এটি আমার পক্ষে কোনও সমস্যা তৈরি করে না।

ফাইলের নাম সমাপ্তি এবং ডিফল্ট BASH সমাপ্তি যুক্ত করতে, -oবিকল্পটি ব্যবহার করুন :

complete -W "${_jupyter_options}" -o bashdefault -o default 'jupyter'

Zsh এ এটি ব্যবহার করতে completeআপনার কমান্ড চালানোর আগে নিম্নলিখিত কোডটি যুক্ত করুন ~/.zshrc:

# make zsh emulate bash if necessary
if [[ -n "$ZSH_VERSION" ]]; then
    autoload bashcompinit
    bashcompinit
fi

আমি কীভাবে এই কাজটি করব bash jupyter <TAB><TAB>?
পাপম্পি

@ পাপাম্পি, আমি মনে করি এটি কেবলমাত্র এক স্তরের সমাপ্তির সাথে কাজ করে - আমি মনে করি এটি 2 স্তরের সাথে এটি করার জন্য আপনার উপরের আরও জটিল উত্তরগুলির প্রয়োজন হবে। এছাড়াও, আমি সম্প্রতি বাশ সম্পূর্ণকরণ সম্পর্কে একটি সুন্দর শালীন টিউটোরিয়াল পড়েছি । এটি আপনার যা প্রয়োজন ঠিক তা করে না তবে সম্ভবত এটি আপনাকে সহায়তা করবে। শুভকামনা!
বেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.