Каков случай использования 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
пожалуйста, дайте мне знать, любой случай использования этого оператора в режиме реального времени или в любом месте, где он является обязательным для использования.
9 ответов:
это больше по историческим причинам. Толстая кишка строится
:в точности эквивалентноtrue. Это традиционное использованиеtrueкогда возвращаемое значение важно, например в бесконечном цикле:while true; do echo 'Going on forever' doneэто традиционное использование
:когда синтаксис оболочки требует команды, но вам нечего делать.while keep_waiting; do : # busy-wait doneThe
: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