Какой вариант использования 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

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

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

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

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

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

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

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

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

A common example. There is a well-known, long-standing issue with shebangs: most systems (including Linux and Cygwin) allow only one argument to be passed to the interpreter. The following shebang:

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

will fire the following command:

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

and not the intended:

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

Thus, you would end up writing a wrapper script, such as:

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

This is where polyglossia enters the stage.

A more specific example. I once wrote a bash script which, among other things, invoked Vim. I needed to give Vim additional setup, which could be done with the option --cmd "arbitrary vimscript command here". However, that setup was substantial, so that inlining it in a string would have been terrible (if ever possible). Hence, a better solution was to write it in extenso in some configuration file, then make Vim read that file with -S "/path/to/file". Hence I ended up with a polyglot bash/vimscript file.

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

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

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

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

Embed POD comments

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

Run-time function binding

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

#!/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

ьным.

Это может быть вопросом мнения, но вот пример. Предположим, что вы создали функцию, которая работает, используя два пути Unix. Он вычисляет «путь изменения» нужно CD с одного пути на другой. Вы накладываете ограничение на свою функцию, так как пути должны начинаться с символа «/ apos; /»; ИЛИ оба не должны.

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)

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

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

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

: в точности эквивалентно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 отлично работает.

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

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

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

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

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there
 20 июл. 2017 г., 21:28
не downvoter, но этот ответ не демонстрирует, как: работает, к сожалению. Приведенный вами пример кажется излишним.
 06 июл. 2017 г., 16:55
Downvoter, объясните, пожалуйста, и я буду рад отредактировать / удалить, если это будет необходимо!
 09 нояб. 2017 г., 00:36
Это немного забавно, если хотите, в угловом случае, но все же довольно интересно, и это может быть умный трюк, чтобы иметь в заднем кармане.
 18 июн. 2018 г., 08:51
То же самое может быть достигнуто с#
 20 июл. 2017 г., 21:53
Вопрос не в том, как это работает, а в том,what is the use case, Это правда, что мой ответ немного похож наstackoverflow.com/a/37170755/6320039, Но это действительно не тот же вариант использования. Я был бы рад улучшить мой ответ, но я действительно не знаю, как здесь ...

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

: << 'EOF'

This part of the script is a commented out

EOF

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

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

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