বাশ কমান্ডের সমাপ্তি কীভাবে কাস্টমাইজ করবেন?


24

ব্যাশে, completeঅন্তর্নির্মিতটি ব্যবহার করে কমান্ড আর্গুমেন্টগুলি কাস্টমাইজড সমাপ্তি সেট আপ করা যথেষ্ট সহজ । উদাহরণস্বরূপ, যদি, একটি সংক্ষিপ্তসার সঙ্গে একটি অনুমান কমান্ডের জন্য foo --a | --b | --c, আপনি করতে পারেনcomplete -W '--a --b --c' foo

এছাড়াও আপনি সমাপ্তির আপনি পেতে যখন আপনি টিপুন কাস্টমাইজ করতে পারেন Tabএকটি এ খালি ব্যবহার প্রম্পট complete -E, যেমন complete -E -W 'foo bar'। তারপর খালি প্রম্পটে ট্যাব টেপা শুধুমাত্র সুপারিশ করবে fooএবং bar

আমি কীভাবে একটি অ- শক্তি প্রম্পটে কমান্ড সমাপ্তি কাস্টমাইজ করব ? যেমন, আমি যদি এখানে বসে থাকি:

anthony@Zia:~$ f

ট্যাব টিপতে সর্বদা সম্পূর্ণ হওয়া কীভাবে কাস্টমাইজ সম্পন্ন হবে foo?

(আমার আসল কেসটি আমি চাই locTABlocalcAnd এবং আমার ভাই, যিনি আমাকে এটি জিজ্ঞাসা করেছিলেন, এটি এমপ্লেয়ারের সাথে চান)।


2
আপনি কেবল aliasing বিবেচনা করেছেন locকরতে localc? আমি বিকল্পগুলির পরামর্শ দিচ্ছি কারণ খনন এবং অনুসন্ধানের বেশ কিছু সময় পরেও এইভাবে বাশ সম্পূর্ণকরণটি কাস্টমাইজ করার কোনও উপায় আমি পাইনি। এটা সম্ভব নাও হতে পারে।
jw013

@ jw013 হ্যাঁ, আমি কিছুক্ষণের জন্য চেয়েছিলাম এবং কিছুও খুঁজে পেলাম না। আমি অর্ধেক আশা করছি যে কেউ zsh এ পরিবর্তন করতে পরামর্শ দেবে। কমপক্ষে zsh যদি এটি করে থাকে তবে আমি বাশের পরবর্তী সংস্করণটিও জেনে স্বাচ্ছন্দ্যে বিশ্রাম নিতে পারি। 😀
derobert

আপনাকে দুবার টিএবি টিপতে হবে এবং এটি আদেশগুলি পূর্ণ করবে।
ফ্লয়েড

1
যদিও অন্য সমস্ত পরিপূর্ণতা ভঙ্গ করবে না? আমি বলতে চাচ্ছি, এমনকি যদি এটা সম্ভব, আপনি আর পেতে সক্ষম হবে locate, locale, lockfileবা কোন অন্যান্য প্রসারণও এর loc। সুনির্দিষ্ট সমাপ্তির জন্য একটি আলাদা কী মানচিত্র করা আরও ভাল পদ্ধতির হতে পারে।
টেরডন

1
আপনি কি এই জাতীয় প্রসঙ্গে একটি উদাহরণ দিতে পারেন (যা কাঙ্ক্ষিত প্রভাব হতে পারে loc<TAB>->localc)?
ড্যামিয়েনফ্রানকোইস

উত্তর:


9

কমান্ডটি সম্পূর্ণ করা (অন্যান্য জিনিস সহ) ব্যাশ রিডলাইন সমাপ্তির মাধ্যমে পরিচালনা করা হয় । এটি স্বাভাবিক "প্রোগ্রামেবল কমপ্লিউশন" (যা কমান্ড শনাক্ত করা হয় কেবল তখনই অনুরোধ করা হয় এবং আপনি যে দুটি বিশেষ কেস উপরে চিহ্নিত করেছেন) এর চেয়ে কিছুটা নিচু স্তরে পরিচালিত হয়।

আপডেট: বাশ -5.0 (জানুয়ারী 2019) এর নতুন প্রকাশটি complete -Iঠিক এই সমস্যার জন্য যুক্ত করেছে।

সম্পর্কিত রিডলাইন কমান্ডগুলি হ'ল:

complete (TAB)
       Attempt to perform completion on the text  before  point.   Bash
       attempts completion treating the text as a variable (if the text
       begins with $), username (if the text begins with  ~),  hostname
       (if  the  text begins with @), or command (including aliases and
       functions) in turn.  If none of these produces a match, filename
       completion is attempted.

complete-command (M-!)
       Attempt  completion  on  the text before point, treating it as a
       command name.  Command completion attempts  to  match  the  text
       against   aliases,   reserved   words,  shell  functions,  shell
       builtins, and finally executable filenames, in that order.

আরও সাধারণভাবে একইভাবে complete -F, এর কয়েকটি ব্যবহার করে কোনও ফাংশনে হস্তান্তর করা যেতে পারে bind -x

function _complete0 () {
    local -a _cmds
    local -A _seen
    local _path=$PATH _ii _xx _cc _cmd _short
    local _aa=( ${READLINE_LINE} )

    if [[ -f ~/.complete.d/"${_aa[0]}" && -x  ~/.complete.d/"${_aa[0]}" ]]; then
        ## user-provided hook
        _cmds=( $( ~/.complete.d/"${_aa[0]}" ) )
    elif [[ -x  ~/.complete.d/DEFAULT ]]; then
        _cmds=( $( ~/.complete.d/DEFAULT ) )
    else 
        ## compgen -c for default "command" complete 
        _cmds=( $(PATH=$_path compgen -o bashdefault -o default -c ${_aa[0]}) )  
    fi

    ## remove duplicates, cache shortest name
    _short="${_cmds[0]}"
    _cc=${#_cmds[*]} # NB removing indexes inside loop
    for (( _ii=0 ; _ii<$_cc ; _ii++ )); do
        _cmd=${_cmds[$_ii]}
        [[ -n "${_seen[$_cmd]}" ]] && unset _cmds[$_ii]
        _seen[$_cmd]+=1
        (( ${#_short} > ${#_cmd} )) && _short="$_cmd"
    done
    _cmds=( "${_cmds[@]}" )  ## recompute contiguous index

    ## find common prefix
    declare -a _prefix=()
    for (( _xx=0; _xx<${#_short}; _xx++ )); do
        _prev=${_cmds[0]}
        for (( _ii=0 ; _ii<${#_cmds[*]} ; _ii++ )); do
            _cmd=${_cmds[$_ii]}
             [[ "${_cmd:$_xx:1}" != "${_prev:$_xx:1}" ]] && break
            _prev=$_cmd
        done
        [[ $_ii -eq ${#_cmds[*]} ]] && _prefix[$_xx]="${_cmd:$_xx:1}"
    done
    printf -v _short "%s" "${_prefix[@]}"  # flatten 

    ## emulate completion list of matches
    if [[ ${#_cmds[*]} -gt 1 ]]; then
        for (( _ii=0 ; _ii<${#_cmds[*]} ; _ii++ )); do
            _cmd=${_cmds[$_ii]}
            [[ -n "${_seen[$_cmds]}" ]] && printf "%-12s " "$_cmd" 
        done | sort | fmt -w $((COLUMNS-8)) | column -tx
        # fill in shortest match (prefix)
        printf -v READLINE_LINE "%s" "$_short"
        READLINE_POINT=${#READLINE_LINE}  
    fi
    ## exactly one match
    if [[ ${#_cmds[*]} -eq 1 ]]; then
        _aa[0]="${_cmds[0]}"
        printf -v READLINE_LINE "%s " "${_aa[@]}"
        READLINE_POINT=${#READLINE_LINE}  
    else
        : # nop
    fi
}

bind -x '"\C-i":_complete0'

এটি আপনার নিজস্ব প্রতি-কমান্ড বা প্রিফিক্স স্ট্রিং হুকটিকে সক্ষম করে ~/.complete.d/। উদাহরণস্বরূপ: যদি আপনি এর ~/.complete.d/locসাথে একটি এক্সিকিউটেবল তৈরি করেন:

#!/bin/bash
echo localc

এটি আপনার প্রত্যাশাটি (মোটামুটি) করবে।

উপরের ফাংশনটি সাধারণ ব্যাশ কমান্ড সমাপ্তির আচরণ অনুকরণ করতে কিছুটা দৈর্ঘ্যে যায় যদিও এটি অসম্পূর্ণ (বিশেষত sort | fmt | columnম্যাচের একটি তালিকা প্রদর্শন করার জন্য সন্দেহজনক ক্যারি-অন)।

যাইহোক , এটির সাথে একটি তুচ্ছ ত্রুটিযুক্ত সমস্যাটি কেবলমাত্র মূল completeফাংশনের সাথে বাঁধার প্রতিস্থাপন করতে একটি ফাংশন ব্যবহার করতে পারে (ডিফল্টরূপে টিএবির সাথে অনুরোধ করা হয়)।

এই পদ্ধতিটি কেবলমাত্র কাস্টম কমান্ড সমাপ্তির জন্য ব্যবহৃত আলাদা কী-বাইন্ডিংয়ের সাথে ভালভাবে কাজ করবে, তবে এটি কেবল তার পরে সম্পূর্ণ সমাপ্তির যুক্তি প্রয়োগ করে না (উদাহরণস্বরূপ কমান্ড লাইনের পরবর্তী শব্দগুলি)। এটি করার জন্য কমান্ড লাইনটি পার্স করা, কার্সার অবস্থানের সাথে সম্পর্কিত এবং অন্যান্য কৌশলগুলি প্রয়োজন যা শেল স্ক্রিপ্টে সম্ভবত বিবেচনা করা উচিত নয় ...


1

আমি জানি না যে আমি এটির জন্য আপনার প্রয়োজনটিকে অজ্ঞাতসারে বুঝেছি কিনা ...
এর দ্বারা বোঝা যায় যে আপনার বাশ কেবল একটি কমান্ড শুরু করে তা জানে f
সমাপ্তির প্রাথমিক ধারণাটি: এটি যদি অস্পষ্ট হয় তবে সম্ভাব্যতাগুলি মুদ্রণ করুন।
সুতরাং আপনি PATHকেবলমাত্র একটি কমান্ডযুক্ত একটি ডিরেক্টরিতে সেট করতে পারেন এবং এই কাজটি পেতে সমস্ত ব্যাশ বিল্টিনগুলি অক্ষম করে।

যাইহোক, আমি আপনাকে এক ধরণের কাজও করতে পারি:

alias _='true &&'
complete -W foo _

আপনি যদি টাইপ করেন তবে _ <Tab>এটি কার্যকর হবে _ fooযা কার্যকর করে foo

তবে তবুও এটি alias f='foo'অনেক সহজ হবে।


0

আপনার জন্য সহজ উত্তর হবে

$ cd into /etc/bash_completion.d
$ ls

শুধু বেসিক আউটপুট

autoconf       gpg2               ntpdate           shadow
automake       gzip               open-iscsi        smartctl
bash-builtins  iconv              openssl           sqlite3
bind-utils     iftop              perl              ssh
brctl          ifupdown           pkg-config        strace
bzip2          info               pm-utils          subscription-manager
chkconfig      ipmitool           postfix           tar
configure      iproute2           procps            tcpdump
coreutils      iptables           python            util-linux
cpio           lsof               quota-tools       wireless-tools
crontab        lvm                redefine_filedir  xmllint
cryptsetup     lzma               rfkill            xmlwf
dd             make               rpm               xz
dhclient       man                rsync             yum.bash
e2fsprogs      mdadm              scl.bash          yum-utils.bash
findutils      module-init-tools  service
getent         net-tools          sh

কেবল আপনার কাঙ্ক্ষিত প্রোগ্রামটি স্বয়ংক্রিয়ভাবে সম্পূর্ণ করতে বাশ সম্পূর্ণ করতে যুক্ত করুন


2
এই ফাইলগুলির মধ্যে শেল স্ক্রিপ্ট রয়েছে, যদি আমি সঠিকভাবে মনে করি তবে কিছু জটিল। আপনি ইতিমধ্যে কমান্ডটি টাইপ করার পরে তারা কেবল যুক্তিগুলি সম্পূর্ণ করে ... তারা কমান্ডটি সম্পূর্ণ করে না।
ডারোবার্ট

আমি বুঝেছি তুমি কি বলতে চাচ্ছো. আপনি যখন এই দস্তাবেজটি একবার দেখতে পারেন: debian-administration.org/article/316/…
unixmiah

-3

এমপ্লেয়ার বাইনারি কোথায় ইনস্টল করা হয়েছে তা জানতে নীচের কমান্ডটি চালান:

which mplayer

বা আপনি যদি জেনে থাকেন তবে নীচের কমান্ডে এমপ্লেয়ার বাইনারিটির পথটি ব্যবহার করুন:

ln -s /path/to/mplayer /bin/mplayer

আদর্শভাবে আপনি যা টাইপ করেন তা $PATHভেরিয়েবলে নির্দিষ্ট সমস্ত ডিরেক্টরিতে অনুসন্ধান করা হয় ।


2
হাই, ম্যাথিউ, ইউনিক্স এবং লিনাক্সে আপনাকে স্বাগতম। আমি মনে করি যে আপনি যে উত্তরটি দিচ্ছেন তার তুলনায় ওপির প্রশ্নটি কিছুটা জটিল। আমি ধারণা করছি mplayerইতিমধ্যে তাদের মধ্যে রয়েছে $PATHএবং তারা (যেমন, ইত্যাদি) দিয়ে শুরু হওয়া সমস্ত বাইনারিগুলির পরিবর্তে কিছু mp<tab>উত্পাদন করতে চাইmplayermpmpage mpcd mpartition mplayer
drs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.