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

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

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

[[email protected]]$ a=11
[[email protected]]$ b=20
[[email protected]]$ c=30
[[email protected]]$ echo $a; : echo $b ; echo $c
10
30

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

 ghoti13 сент. 2012 г., 13:03
Обратите внимание, что: встроенный в Bourne Shell и Ksh существует, а также Bash.
 Stephane Rouberol13 сент. 2012 г., 12:58
 choroba13 сент. 2012 г., 13:35
Смотрите также: вtldp.org/LDP/abs/html/special-chars.html
 Steven Lu13 июл. 2013 г., 06:25
Как это не реальный вопрос? Я думаю это'Это действительно хороший вопрос. У меня даже есть хорошее применение, но я могуне опубликовать ответ.

Ответы на вопрос(9)

ьным.

Это может быть вопросом мнения, но здесьЭто пример. Позволять'Предположим, выМы создали функцию, которая работает, используя два пути 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)

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

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

 chepner05 нояб. 2014 г., 15:54
Если вы отвечаете на вопрос о цели:, вы должны использовать:неtrueв ответ. Тем не менее, самый простой способ отрицать условное здесь, это использовать один[[ ... ]] введите команду и добавьте к нему префикс:.!if ! [[ ( ... && ... ) || ( ... && ... ) ]]; then
 Bitdiot05 нояб. 2014 г., 15:58
Ах, очень мило, и я должен проголосовать за мой ответ. Хммм .... яЯ все еще думаю о примерах, где я должен был использовать предложение без операции. Это лучшее, что я придумал.
 chepner05 нояб. 2014 г., 16:08
Это'на самом деле только для обратной совместимости, хотя: ${...=...} возможно, выглядит менее неловко, чемtrue ${...=...}, Некоторые могут предпочестьwhile :; do вwhile true; do для краткости.

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

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

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

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

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

dbg=${DBG:-''}

function _log_dbg {
    echo >&2 "[DBG] [email protected]"
}

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

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

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'

Баш можетне иметь пустых блоков (WTF). Итак, вы добавляете no-op:

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

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

if [ "$foo" != "1" ]
then
    : echo Success
fi
Решение Вопроса

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

while true; do
  echo 'Going on forever'
done

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

while keep_waiting; do
  : # busy-wait
done

: встроенные даты вплоть доТомпсон оболочка, это былоподарок вUnix v6.: был индикатор метки для оболочки Томпсонаgoto заявление. На ярлыке может быть любой текст, поэтому: удваивается как индикатор комментария (если нетgoto comment, затем: comment это фактически комментарий).Оболочка Борна А не было»иметьgoto но сохранил.:

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

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

 DevSolar05 нояб. 2014 г., 15:23
@JonathanLeffler: Позор мне, но я нене понимаю Что будет с?: * * *
 Jonathan Leffler13 сент. 2012 г., 15:26
Хорошее резюме. Кроме того, оригинальная оболочка Bourne нет использовать# для комментариев (или#!/bin/sh она взорвалась);: Команда представила комментарии и горе гореЯ программист, который сделал хорошую коробку звезд в их комментариях:: **** (или хуже,: * * *).
 chepner05 нояб. 2014 г., 15:48
Так как: является командой, оболочка все еще должна обработать свои аргументы, прежде чем она сможет обнаружить, что: игнорирует их. В основном, вы просто заставляете оболочку выполнять дополнительную работу по расширению* в список файлов в текущем каталоге; это победилоЭто на самом деле влияет на работу скрипта.
 Keith Thompson12 мая 2016 г., 03:05
Я иногда используюwhile : ; do ... ; done если я хочу быстрый и грязный бесконечный цикл. (Обычно тамсsleep в цикле, и я нажимаю Ctrl-C, чтобы убить его.)
 Jack O'Connor07 нояб. 2015 г., 23:14
Я полагаю, что это может привести к сбою в работе вашего сценария, если вы запустите его в каталоге с большим количеством файлов, что заставит расширение glob превысить ограничение длины команды? Может быть, только если у вас естьset -e на. Во всяком случае, надеюсь, мы все можем просто согласиться использовать# :)

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

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

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

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

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

Типичный пример. Существует известная давняя проблема с 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", Однако эта настройка была существенной, так что встраивание ее в строку было бы ужасным (если возможно). Следовательно, лучшим решением было бы написатьв экстенсе в каком-то файле конфигурации, затем заставьте Vim прочитать этот файл-S "/path/to/file", Поэтому я получил файл bash / vimscript для полиглота.

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

: << 'EOF'

This part of the script is a commented out

EOF

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

 Beejor08 дек. 2017 г., 22:29
Классный трюк! Специально для заметок и кода, требующих десятки "#"когда в жесткой упаковке. Побочным эффектом является то, что в отличие от строк комментариев, некоторые подсветки синтаксиса игнорируют heredocs, окрашивая их как обычный код (или, по крайней мере, обычный текст). Это может быть полезно при проверке закомментированного кода или избавлении от абзацев в цвете неоновых комментариев. Единственное предостережение заключается в том, что такие блоки должны быть отмечены как комментарии в общем коде, поскольку синтаксис уникален и может привести к путанице. Опять же, это оболочка, которую мыВы говорите о том, где вероятность путаницы является системной.

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

 Beejor08 дек. 2017 г., 21:54
Мы нашли это полезным для некоторых приложений, вызывающих сценарии оболочки. Например, Automator на Mac завершит работу при ошибке и не скажет вам, почему. Но используя|| : затем позже обработать ошибку самостоятельно сexit 0 позволит вам отображать все stdout и stderr в окне приложения во время отладки. Рассматривать{ foo ... 2>&1; } || : что гораздо проще, чем устанавливать более сложные ловушки и если-то.
игнорироватьalias аргументы

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

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there
 qodeninja20 июл. 2017 г., 21:28
не downvoter, но этот ответ не демонстрирует, как: работает, к сожалению. Приведенный вами пример кажется излишним.
 Mike S09 нояб. 2017 г., 00:36
Это немного забавно, если хотите, в угловом случае, но все же довольно интересно, и у вас может получиться хитрый приемзадний карман.
 Ulysse BN20 июл. 2017 г., 21:53
Вопрос не в том, как это работает, а в том,какой вариант использования, Это'правда, мой ответ немного похож наstackoverflow.com/a/37170755/6320039, Но это действительно не тот же вариант использования. Я'Буду рад улучшить мой ответ, но я действительно нене знаю, как здесь ..
 Zoey Hewll18 июн. 2018 г., 08:51
То же самое может быть достигнуто с#
 Ulysse BN06 июл. 2017 г., 16:55
Downvoter, объяснись, пожалуйста, и яЯ буду рад отредактировать / удалить, если это будет необходимо!

Вы бы использовали: предоставить команду, которая успешно, но неничего не делай. В этом примеремногословие» команда отключена по умолчанию, установив ее:, 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  
 qodeninja20 июл. 2017 г., 21:30
строго говоря, присвоение значения переменнойделать что-то"следовательно, почему это не такне выдать ошибку в вашем случае заявления.
 Lightness Races in Orbit23 окт. 2017 г., 16:26
@qodeninja: Никто не утверждал, что присвоение переменной "Ничего не сделал"; дело в том, что$(verbosity $i) позже (и условно) ничего не делает.

Ваш ответ на вопрос