Отключите заполнение клавишей Tab в Bash для некоторого каталога, который содержит большое количество файлов?

Статус выхода составляет 8 битов intergers (хотя большинство оболочек (ksh93 быть исключением) усечет его к 7 битам, поскольку они используют бит 8 для сообщенных процессов), таким образом, он будет только работать, если pid будет между 0 и 127. Получите pid от канала вместо статуса выхода:

SSH_PID=$(
expect <<EOD
...
spawn -noecho ssh ...
puts [exp_pid]
...
EOF
)
19
13.10.2014, 17:50
3 ответа

Поиск человеко-страниц

При поиске команд вместо сопоставления имен двоичных файлов команд можно сопоставить имена человеко-страниц в качестве альтернативы; Это может иметь смысл, поскольку man уже предоставляет эту функцию по умолчанию:

$ man --sections=1,8 --where --all --regex '^mkdi' 
/usr/share/man/man1/mkdir.1.gz
/usr/share/man/man1/mkdirhier.1.gz
/usr/share/man/man1/mkdiskimage.1.gz

Использование sed для извлечения только имен команд:

$ man --sections=1,8 --where --all --regex '^mkdi' | \
    sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$/\1/'
mkdir
mkdirhier
mkdiskimage

И выполнение , которые для имен команд тоже:

$ man --sections=1,8 --where --all --regex '^mkdi' | \
    sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$/\1/' | xargs which 
/bin/mkdir
/usr/bin/mkdirhier
/usr/bin/mkdiskimage

узоры являются регулярными выражениями, поэтому ^ добавляется для соответствия только в начале имени.
В синтаксисе образца, подобном оболочке glob, замените -regex на --wildcard ,
как человек... --wildcard 'mkdi *' |... .

В качестве функции оболочки:

whichmatch() {       
    man --sections=1,8 --where --all --regex "$@" |
        sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$/\1/' |
        xargs which
}

используется как

whichmatch '^mkdi'

Для приблизительного совпадения имен команд , который может использоваться вместо man .

-121--77994-

Используйте числовую сортировку

Команда sort имеет опцию -g ( -general-numeric-sort ), которая может использоваться для сравнения на < , «меньше» или > , «больше, чем», путем нахождения минимального значения

Эти примеры находят минимум:

$ printf '12.45\n10.35\n' | sort -g | head -1
10.35

Поддерживает E-нотацию

Работает с довольно общей нотацией плавающих точек чисел, как и с E-нотацией

$ printf '12.45E-10\n10.35\n' | sort -g | head -1
12.45E-10

Обратите внимание на E-10 , делая первое число 0.000000001245 , действительно меньше 10,35 .

Можно сравнить с бесконечностью

Плавающий стандарт точки IEEE754 определяет некоторые специальные значения. Для этих сравнений интересными являются INF для бесконечности. Существует также отрицательная бесконечность; Оба значения являются хорошо определенными значениями в стандарте.

$ printf 'INF\n10.35\n' | sort -g | head -1
10.35
$ printf '-INF\n10.35\n' | sort -g | head -1
-INF

Чтобы найти максимальное использование sort -gr вместо sort -g , сторнируйте порядок сортировки:

$ printf '12.45\n10.35\n' | sort -gr | head -1
12.45

Операция сравнения

Для реализации сравнения < («меньше»), чтобы его можно было использовать в , если и т.д., сравните минимальное значение с одним из значений. Если минимум равен значению, по сравнению с текстом , это меньше, чем другое значение:

$ a=12.45; b=10.35                                    
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?
1
$ a=12.45; b=100.35                                    
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?                                              
0
-121--20299-

Это не идеально, но затем снова bash завершение довольно сложная вещь...

Самый простой способ на основе команды, это немного более гибкий, чем FIGNORE , вы можете сделать:

 complete -f -X "/myproject/data/*" vi

Это дает указание автозавершить, что завершение для vi для файлов, и удалить узоры, соответствующие фильтру -X . Минус в том, что образец не нормализован, поэтому ../data и вариации не будут совпадать.

Следующей лучшей функцией может быть пользовательская функция PROMPT _ COMMAND :

# associative arrays of non-autocomplete directories
declare -A noacdirs=([/myproject/data]=1 )

function _myprompt {
    [[ -n "${noacdirs[$PWD]}" ]] && {
       echo autocomplete off
       bind 'set disable-completion on'
    } || {
       echo autocomplete on
       bind 'set disable-completion off'
    }
} 

PROMPT_COMMAND=_myprompt

Эта функция отключает завершение (полностью) при нахождении в каталоге, но отключает его для каждого пути, а не только для файлов в этом каталоге.

В более общем случае было бы полезно выборочно отключить это для определенных путей,Но я считаю, что единственный способ - использовать функцию завершения по умолчанию (bash-4.1 и позже с complete -D ) и много путаницы.

Это должно работать для вас, но это может иметь непреднамеренные побочные эффекты (т.е. изменения ожидаемого завершения в некоторых случаях):

declare -A noacdirs=([/myproject/data]=1 )

_xcomplete() {
    local cur=${COMP_WORDS[COMP_CWORD]} # the current token

    name=$(readlink -f "${cur:-./}")  # poor man's path canonify
    dirname=$(dirname "$name/.")

    [[ -n "${noacdirs[$dirname]}" ]] && {
        COMPREPLY=( "" )   # dummy to prevent completion
        return
    }
    # let default kick in
    COMPREPLY=()
}

complete -o bashdefault -o default -F _xcomplete vi

Это работает для завершения vi , другие команды могут быть добавлены по мере необходимости. Он должен остановить завершение для файлов в именованных каталогах независимо от пути или рабочего каталога.

Я считаю, что общий подход с complete -D заключается в динамическом добавлении функций завершения для каждой команды по мере ее появления. Также может потребоваться добавить complete -E (завершение имени команды, когда входной буфер пуст).


Обновить Вот гибридная версия PROMPT _ COMMAND и решения функции завершения, это немного проще понять и взломать я думаю:

declare -A noacdirs=([/myproject/data]=1 [/project2/bigdata]=1)

_xcomplete() {
    local cmd=${COMP_WORDS[0]}
    local cur=${COMP_WORDS[COMP_CWORD]} # the current token

    [[ -z "$cur" && -n "$nocomplete" ]] && {
        printf "\n(restricted completion for $cmd in $nocomplete)\n"  
        printf "$PS2 $COMP_LINE"
        COMPREPLY=( "" )   # dummy to prevent completion
        return
    }
    COMPREPLY=()       # let default kick in
}

function _myprompt {
    nocomplete=
    # uncomment next line for hard-coded list of directories
    [[ -n "${noacdirs[$PWD]}" ]] && nocomplete=$PWD
    # uncomment next line for per-directory ".noautocomplete"
    # [[ -f ./.noautocomplete ]] && nocomplete=$PWD
    # uncomment next line for size-based guessing of large directories
    # [[ $(stat -c %s .) -gt 512*1024 ]] && nocomplete=$PWD
} 

PROMPT_COMMAND=_myprompt
complete -o bashdefault -o default -F _xcomplete vi cp scp diff

Эта функция приглашения устанавливает переменную nocomplete при вводе одного из настроенных каталогов. Измененное поведение завершения запускается только в том случае, если переменная не пуста и , только когда вы пытаетесь выполнить из пустого ряда, таким образом разрешая завершение частичных имен (удалите условие -z «$ cur» , чтобы предотвратить полное завершение). Прокомментируйте две строки printf для бесшумной работы.

Другие параметры включают файл флага .noautocomplete , который можно коснуться в каталоге при необходимости; и угадывание размера каталога с использованием GNU stat . Можно использовать любой или все эти три варианта.

(Метод stat является только предположением , сообщаемый размер каталога увеличивается вместе с его содержимым, это «высокая отметка воды», которая обычно не уменьшается при удалении файлов без какого-либо административного вмешательства. Это дешевле, чем определить реальное содержимое потенциально большого каталога. Точное поведение и приращение для каждого файла зависит от базовой файловой системы. Я нахожу его надежным индикатором на linux ext2/3/4 систем по крайней мере.)

bash добавляет дополнительное пространство, даже когда возвращается пустое завершение (это происходит только при завершении в конце строки). Для предотвращения этого можно добавить -o nospace в команду complete .

Один оставшийся ниггль заключается в том, что если вы задокументируете курсор до начала маркера и нажмете вкладку, завершение по умолчанию снова начнется. Считайте это особенностью; -)

(Или вы могли бы обойти с $ {COMP _ LINE: $ COMP _ ПУНКТ 1: 1} , если вы любите сверхинженерию, но я нахожу, что сам bash не может установить переменные завершения надежно при резервном копировании и попытке завершения в середине команды.)

9
27.01.2020, 19:45

Ваш Data каталог содержит файлы с определенным суффиксом, например, .out , тогда вы можете установить вашу вариабельную Bash на . OUT », и они будут игнорироваться. Хотя также можно использовать имена каталогов, это не помогает в текущих именах рабочих каталога.

Пример:

Создайте тысячи тестовых файлов 100 КБ на физическом хосте с помощью HDDS RAID 1:

for i in {1..200000}; do dd if=/dev/urandom bs=102400 count=1 of=file$i.json; done

Установите переменную Bash :
$ Fignore = "Json"

Создать Тестовый файл:
TEST TEST. NOUT

Тест

на 5000 файлов:

$ ls *.json|wc -l
5587
$ vi test.out

Нет задержки между вкладкой VI и Single до Test.out появляется.

Испытание на 50 000 файлов:

$ ls *.json|wc -l
51854
$ vi test.out

Одиночная вкладка создает фракцию второй задержки до Test.Out .

Испытание на 200 000 Файлы:

$ ls *.json|wc -l
bash: /bin/ls: Argument list too long
$ ls | awk 'BEGIN {count=0} /.*.json/ {count++} END {print count}'
200000
$ vi test.out

Задержка 1 секунды между вкладкой VI и Single до Test.out появляется.

Список литературы:

Оценка от человека Bash

FIGNORE
              A  colon-separated  list  of  suffixes to ignore when performing filename completion (see READLINE below).  A filename whose suffix matches one of the entries in FIGNORE is
              excluded from the list of matched filenames.  A sample value is ".o:~".
6
27.01.2020, 19:45

Угадайте, что это то, что вы хотите (заимствовал какой-то код из @ Mr.Spuratic)

Примечание. Это не мешает вам нажатию вкладку, используя полный путь (например, VIM / Directory / Contital / Lots / файлы < Tab>

function cd() {
  builtin cd "$@"
  local NOCOMPLETION=( "/" "/lib" )
  local IS_NOCOMPLETION=0
  for dir in "${NOCOMPLETION[@]}"
  do
    echo $dir
    if [[ $(pwd) == "$dir" ]]
    then
      echo "disable completion"
      bind "set disable-completion on"
      IS_NOCOMPLETION=1
      return
    fi                                                                                                                                                                                              
  done
  if [[ $IS_NOCOMPLETION -eq 0 ]]
  then
    echo "enable completion"
    bind "set disable-completion off"
  fi
}  
0
27.01.2020, 19:45

Теги

Похожие вопросы