Каков случай использования noop [:] в bash?



Я искал noop в bash (:), но не смог найти никакой хорошей информации. Какова точная цель или случай использования этого оператора?



Я попытался следовать, и это работает так для меня:



[mandy@root]$ a=11
[mandy@root]$ b=20
[mandy@root]$ c=30
[mandy@root]$ echo $a; : echo $b ; echo $c
10
30


пожалуйста, дайте мне знать, любой случай использования этого оператора в режиме реального времени или в любом месте, где он является обязательным для использования.

581   9  

9 ответов:

это больше по историческим причинам. Толстая кишка строится : в точности эквивалентно true. Это традиционное использование true когда возвращаемое значение важно, например в бесконечном цикле:

while true; do
  echo 'Going on forever'
done

это традиционное использование : когда синтаксис оболочки требует команды, но вам нечего делать.

while keep_waiting; do
  : # busy-wait
done

The : builtin датируется вплоть до Томпсон оболочки, это было присутствует in Unix v6. : был индикатором метки для оболочки Томпсона goto заявление. Метка может быть любым текстом, так что : удвоился в качестве индикатора комментариев (если нет goto comment, потом : comment это фактически комментарий). Элемент Bourne shell не было goto но сохранил :.

распространенная идиома, которая использует : и : ${var=VALUE}, который устанавливает var до VALUE если он был отключен и ничего не делает, если var уже был набор. Эта конструкция существует только в виде замены переменной, и эта замена переменной должна быть частью команды каким-то образом: команда no-op отлично работает.

см. также какой цели служит встроенная толстая кишка?.

я использую его для операторов if, когда я комментирую весь код. Например, у вас есть тест:

if [ "$foo" != "1" ]
then
    echo Success
fi

но вы хотите временно прокомментировать все, что содержится внутри:

if [ "$foo" != "1" ]
then
    #echo Success
fi

что приводит к тому, что bash выдает синтаксическую ошибку:

line 4: syntax error near unexpected token `fi'
line 4: `fi'

Bash не может иметь пустые блоки (WTF). Поэтому вы добавляете no-op:

if [ "$foo" != "1" ]
then
    #echo Success
    :
fi

или вы можете использовать no-op, чтобы закомментировать строки:

if [ "$foo" != "1" ]
then
    : echo Success
fi

можно использовать : чтобы предоставить команду, которая выполняется успешно, но ничего не делает. В этом примере команда "verbosity" отключена по умолчанию, установив ее в :. В параметр 'V' включает.

#!/bin/sh
# example
verbosity=:                         
while getopts v OPT ; do          
   case $OPT in                  
       v)        
           verbosity=/bin/realpath 
       ;;
       *)
           exit "Cancelled"
       ;;             
   esac                          
done                              

# `$verbosity` always succeeds by default, but does nothing.                              
for i in * ; do                   
  echo $i $($verbosity $i)         
done                              

$ example
   file

$ example -v
   file /home/me/file  

Если вы используете set- e затем || : - это отличный способ не выйдите из скрипта, если произойдет сбой (он явно делает его проходным).

два моих.

вставить POD комментарии

довольно фанки применение : на встраивание комментариев POD в Скрипты bash, так что man-страницы можно быстро создать. Конечно, в конечном итоге можно было бы переписать весь скрипт на Perl ; -)

привязка функции времени выполнения

Это своего рода шаблон кода для привязки функции во время выполнения. F. i., есть функция отладки, чтобы сделать что-то, только если определенный флаг набор:

#!/bin/bash
# noop-demo.sh 
shopt -s expand_aliases

dbg=${DBG:-''}

function _log_dbg {
    echo >&2 "[DBG] $@"
}

log_dbg_hook=':'

[ "$dbg" ] && log_dbg_hook='_log_dbg'

alias log_dbg=$log_dbg_hook


echo "Testing noop alias..."
log_dbg 'foo' 'bar'

вы получаете:

$ ./noop-demo.sh 
Testing noop alias...
$ DBG=1 ./noop-demo.sh 
Testing noop alias...
[DBG] foo bar

одно использование - это многострочные комментарии или закомментировать часть вашего кода для целей тестирования, используя его в сочетании с файлом here.

: << 'EOF'

This part of the script is a commented out

EOF

не забудьте использовать кавычки вокруг EOF Так что любой код внутри не оценивается, как $(foo). Также может быть стоит использовать интуитивное имя Терминатора, например NOTES,SCRATCHPAD или TODO.

иногда предложения no-op могут сделать ваш код более читаемым.

это может быть вопрос мнения, но вот пример. Предположим, вы создали функцию, которая работает, используя два пути unix. Он вычисляет "путь изменения", необходимый для cd от одного пути к другому. Вы устанавливаете ограничение на свою функцию, что пути должны начинаться с '/' или оба не должны.

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        true      # continue with function
    else
        return 1  # Skip function.
    fi

некоторые разработчики захотят удалить no-op, но это будет означать отрицание условно:

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" != / || "$fromC" == / ]] && [[ "$toC" == / || "$fromC" != / ]]
    then
        return 1  # Skip function.
    fi

Теперь -на мой взгляд-это не так ясно из предложения if-условия, в которых вы хотите пропустить выполнение функции. Чтобы устранить no-op и сделать это четко, вы хотели бы переместить предложение if из функции:

    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        cdPath=$(chgPath pathA pathB)   # (we moved the conditional outside)

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

Так как часто это происходит? Не очень часто. Может быть, один или два раза в год. Такое бывает достаточно часто, чтобы вы знали об этом. Я не уклоняюсь от его использования, когда я думаю, что это улучшает читаемость моего кода (независимо от языка).

игнорировать alias аргументы

иногда вы хотите иметь псевдоним, который не принимает никаких аргументов. Вы можете сделать это с помощью ::

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there

несколько связанных с ответ, я считаю, это не удобно рубить полиглот скрипты. Например, вот допустимый комментарий как для bash, так и для vimscript:

":" #    this is a comment
":" #    in bash, ‘:’ is a no-op and ‘#’ starts a comment line
":" #    in vimscript, ‘"’ starts a comment line

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


как почему сделал бы кто-нибудь такую хитрую вещь как писать сценарий полиглота (помимо того, что это круто): это оказывается полезным в ситуациях, когда мы обычно пишем несколько файлов сценариев на нескольких разных языках, с file X ссылка на файл Y.

в такой ситуации, объединяя оба скрипта в один, полиглот файл позволяет избежать любой работы в X для определения пути к Y (это просто ""). Что еще более важно, это делает его более удобным для перемещения или распространить программа.

  • общий пример. существует известная, давняя проблема с shebangs: большинство систем (включая Linux и Cygwin) позволяют только один аргумент для передачи интерпретатору. Следующий притон:

    #!/usr/bin/env interpreter --load-libA --load-libB
    

    сработает следующая команда:

    /usr/bin/env "interpreter --load-libA --load-libB" "/path/to/script"
    

    а не то, что предполагалось:

    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"
    

    таким образом, вы в конечном итоге написание сценария оболочки, такие как:

    #!/usr/bin/env sh
    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"
    

    вот где полиглоссия выходит на сцену.

  • более конкретный пример. однажды я написал сценарий bash, который, среди прочего, вызвал Vim. Мне нужно было дать Vim дополнительную настройку, которую можно было бы сделать с помощью опции --cmd "arbitrary vimscript command here". Однако эта настройка была существенной, так что встраивание ее в строку было бы ужасно (если это вообще возможно). Следовательно, лучшим решением было написать его полностью in какой-то файл конфигурации, а затем заставить Vim прочитать этот файл с помощью -S "/path/to/file". Поэтому я закончил с файлом polyglot bash / vimscript.

Comments

    Ничего не найдено.