Что является утилитой: команда в сценариях оболочки, учитывая, что это явно ничего не делает?

По умолчанию iconv отказывается преобразовывать файл, если он содержит символы, которые не существуют в целевом наборе символов. Использовать //TRANSLIT “понизить” такие символы.

iconv -f utf-8 -t iso8859-1//TRANSLIT
27
13.04.2017, 15:36
9 ответов

Я обычно использую true в циклах; я думаю, что это более ясно:

while true; do
    ...
done

Одно место я нашел это : действительно удобно, то, в случае, если операторы, если необходимо соответствовать почти, не хотят на самом деле делать что-либо. Например:

case $answer in
    ([Yy]*) : ok ;;
    (*)     echo "stop."; exit 1 ;;
esac
19
27.01.2020, 19:39
  • 1
    я соглашаюсь. true для условия, : для NOP –  jw013 27.04.2012, 23:34
  • 2
    принимает case a in a ) ;; esac. Есть ли некоторые оболочки, которые не принимают это? –  Kaz 28.04.2012, 03:00
  • 3
    @Kaz: Согласно POSIX окружают грамматику, case ${var} in value);; *) do_something;; esac приемлемо. : команда не нужна для пустых ящиков. включение –  Richard Hansen 07.05.2012, 21:47

Первоначально, это использовалось, чтобы решить, что это была программа Оболочки Bourne, в противоположность скомпилированной программе C. Это было перед хижиной и несколькими языками сценариев (csh, жемчуг). Можно все еще запустить скрипт, запускающийся только с ::

$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy

Это будет обычно запускать скрипт против $SHELL (или /bin/sh).

С тех пор основное использование должно оценить аргументы. Я все еще использую:

: ${EDITOR:=vim}

установить значение по умолчанию в сценарии.

12
27.01.2020, 19:39

: полезно для записи циклов, которые должны быть завершены из.

while :
do
    ...stuff...
done

Это будет работать навсегда если break или exit назван, или оболочка получает завершающийся сигнал.

11
27.01.2020, 19:39
  • 1
    , я чувствую это while true; do ...; done передает намерения читателю лучше, чем while :; do ...; done –  Richard Hansen 07.05.2012, 21:31

Когда Вы хотите, "если" оператор в сценариях оболочки, Вы или не используете "не" условие, которое может глупо искать некоторые тесты, или Вы используете ':' в истинном пункте, с реальным кодом в ложном пункте.

if [ some-exotic-condition ]
then
    :
else
    # Real code here
fi

"Экзотическое условие" могло быть чем-то, что Вы не хотите инвертировать, или это просто намного более ясно, если Вы не используете "отрицательную логику".

9
27.01.2020, 19:39
  • 1
    Это также обнаруживается в сценариях, сгенерированных autoconf потому что намного легче добавить значение по умолчанию : поскольку пустые ответвления, чем он должны выяснить, как инвертировать условие. –  Dietrich Epp 28.04.2012, 01:11
  • 2
    я не вижу как всовывание a ! перед [ some-exotic-condition ] является глупым, но лишнее : else после того, как это не является глупым. –  Kaz 28.04.2012, 03:02
  • 3
    @Kaz имеет положительную сторону. Давайте иметь в виду, что придумывающий экзотические условия является трудным в лучшем случае Если необходимо инвертировать все это, это - одна вещь, но она могла бы просто сделать условие менее ясным. Делает a'!' инвертируйте целое условие или просто первый срок? Лучше всего иметь a ':' истинный пункт иногда. –  Bruce Ediger 03.05.2012, 18:18
  • 4
    ! маркер инвертирует весь элемент канала команды. while ! grep ... ; do ... done или if ! [ ... ] ; then ... fi. Это является в основном внешним к test/[] синтаксис. См.: pubs.opengroup.org/onlinepubs/9699919799/utilities / … –  Kaz 03.05.2012, 20:49

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

if condition ; then
    :# temporarily commented out command
fi

Без: у нас есть недостающая последовательность команды, которая является синтаксической ошибкой.

5
27.01.2020, 19:39

Существует два случая, где я нахожу : полезный:

Переменные присвоения по умолчанию

#!/bin/sh

# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"

# print the value of the VAR variable.  Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"

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

VAR="other value" ./script

${VAR=value} синтаксис говорит для установки VAR кому: value если VAR уже не установлен, затем расширьтесь до значения переменной. Так как мы просто еще не заботимся о значении переменной, это передается как аргумент никакой-op команде : выбрасывать его.

Даже при том, что : не-op команда, расширение выполняется оболочкой (не : команда!) прежде, чем работать : управляйте, таким образом, переменное присвоение все еще происходит (если применимо).

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

Следующий сценарий также работал бы:

#!/bin/sh

# print the value of the VAR variable.  Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"

Но вышеупомянутое намного более трудно поддержать. Если использование строки ${VAR} добавляется выше этого printf строка, расширение присвоения по умолчанию должно быть перемещено. Если разработчик забывает перемещать то присвоение, ошибка представлена.

Что-то, чтобы вставить пустой условный блок

Пустых условных блоков нужно обычно избегать, но они иногда полезны:

if some_condition; then
    # todo:  implement this block of code; for now do nothing.
    # the colon below is a no-op to prevent syntax errors
    :
fi

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

if [ -f foo ] && bar || baz; then
    :
else
    do_something_here
fi

возможно легче читать, чем:

if ! [ -f foo ] || ! bar && ! baz; then
    do_something_here
fi

Однако я полагаю, что существует несколько альтернативных подходов, которые лучше, чем пустой истинный блок:

  1. Поместите условие в функцию:

    exotic_condition() { [ -f foo ] && bar || baz; }
    
    if ! exotic_condition; then
        do_something_here
    fi
    
  2. Поместите условие в фигурных скобках (или круглые скобки, но круглые скобки порождают процесс подоболочки, и любые изменения, внесенные в среду в подоболочке, не будут видимы вне подоболочки) перед отрицанием:

    if ! { [ -f foo ] && bar || baz; } then
        do_something_here
    fi
    
  3. Использовать || вместо if:

    [ -f foo ] && bar || baz || {
        do_something_here
    }
    

    Я предпочитаю этот подход, когда реакция является простой остротой, такой как утверждение условий:

    log() { printf '%s\n' "$*"; }
    error() { log "ERROR: $*" >&2; }
    fatal() { error "$@"; exit 1; }
    
    [ -f foo ] && bar || baz || fatal "condition not met"
    
4
27.01.2020, 19:39

В старой предварительной оболочке Bourne в древних версиях UNIX, : команда была первоначально предназначена для определения маркировок для goto (это была отдельная команда, которая проветривает вход туда, где маркировка найдена, таким образом, маркировки не могли быть отдельным синтаксисом, о котором знает оболочка. if была также отдельная команда.) Это скоро привыкло для комментариев, прежде чем был синтаксис комментария (# использовался для клавиши Backspace), и в эти дни вокруг для совместимости так же как что-либо.

1
27.01.2020, 19:39

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

0
27.01.2020, 19:39
  • 1
    Это не будет точно комментарий с тех пор : echo write this line > myfile все еще создаст пустой файл. –  Arcege 27.04.2012, 21:46
  • 2
    Как объяснено в ссылке в вопросе, : не соответствующий механизм комментария. –  jw013 27.04.2012, 21:55

Команда оболочки «:» существует потому, что в исходной оболочке v1, оболочке Томпсона, «:» вводилась метка, которая потенциально была целью команды goto.

В статье оболочки Томпсона Википедии отмечается, что:

The shell's design was intentionally minimalistic; even the if and goto statements, essential for control of program flow, were implemented as separate commands.

Исходный код V1 Unix содержит исходный код автономной команды goto . У него есть функция main(), что делает его отдельной программой. Кажется, что он читает стандартный ввод, пока не найдет символ " :", затем он читает ноль или более символов пробела ASCII, а затем метку. Если это метка, которую он в настоящее время ищет, он выполняет lseek()на стандартном вводе.

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

1
08.04.2020, 23:28

Теги

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