admin / 18.11.2017
Отсутствуют пробелы.
означает
тебе нужно
или даже
которая работает даже при .
Если вам не нужна переносимость для других оболочек, вы можете использовать двойные квадратные скобки в bash.
Котировки не нужны (на самом деле, с правой стороны они имеют особое значение – они предотвращают расширение). Вы можете использовать вместо , также.
Содержание
Код выглядит так:
use strict; use warnings; print 42 «\n»; my $name = «Foo»;
а сообщение об ошибке
String found where operator expected at ex.pl line 4, near «42 «\n»» (Missing operator before «\n»?) syntax error at ex.pl line 4, near «42 «\n»» Execution of ex.pl aborted due to compilation errors.
Оно четко указывает местонахождение проблемы, но, как показывает опыт, многие люди торопятся открыть свой редактор и исправить ошибку, толком не прочитав сообщение. Они вносят изменения в надежде, что этим решат проблему, а в итоге получают еще одно сообщение об ошибке.
В данном случае проблема была в том, что мы забыли запятую (,) после числа 42. Эта строчка должна выглядеть так: print 42, «\n»;.
В этом коде мы пропустили оператор конкатенации .
и получили такое же сообщение об ошибке:
use strict; use warnings; my $name = «Foo» «Bar»; String found where operator expected at ex.pl line 4, near «»Foo» «Bar»» (Missing operator before «Bar»?) syntax error at ex.pl line 54, near «»Foo» «Bar»» Execution of ex.pl aborted due to compilation errors.
На самом деле код должен был выглядеть так: my $name = «Foo» . «Bar»;.
Этот код
use strict; use warnings; my $x = 23; my $z = $x 19;
выдает такую ошибку:
Number found where operator expected at ex.pl line 5, near «$x 19» (Missing operator before 19?) syntax error at ex.pl line 5, near «$x 19» Execution of ex.pl aborted due to compilation errors.
Здесь, видимо, не хватает оператора сложения + или умножения *, ну или оператора повтора x.
Отсутствующая запятая не всегда понимается интерпретатором, как пропущенный оператор. Например, этот код:
use strict; use warnings; my %h = ( foo => 23 bar => 19 );
Генерирует такую ошибку: syntax error at … line …, near «bar», без дополнительных деталей.
Добавление запятой после числа 23 исправит код:
my %h = ( foo => 23, bar => 19 );
Я предпочитаю добавлять запятую после каждой пары в хэше (то есть, в данном случае, после 19):
my %h = ( foo => 23, bar => 19, );
Эта привычка в большинстве случаев помогает избежать таких ошибок.
use strict; use warnings; my $x = 23; my $y = 19; my $z = $x $y; Scalar found where operator expected at … line 7, near «$x $y» (Missing operator before $y?) syntax error at … line 7, near «$x $y» Execution of … aborted due to compilation errors.
Опять же, между $x и $y может быть числовой или строковый оператор.
use strict; use warnings; my @x = (23); my $z = 3 @x;
Знаете ли вы другие интересные случаи, в которых мы получаем такую синтаксическую ошибку?
Это сообщение об ошибке встречается действительно часто. Однако понять его может быть довольно сложно.
Дело в том, что люди знают о числовых операторах и строковых операторах, но не рассматривают запятую (,) как оператор. Терминология сообщения об ошибке немного вводит их в заблуждение.
Давайте рассмотрим пару примеров:
Давайте разберемся как передавать и обрабатывать аргументы скрипта и ознакомимся с основными управляющими конструкциями bash.
В простом скрипте из предыдущей статьи мы использовали переменную «$1«, которая содержит первый аргумент командной строки при вызове скрипта. Аналогично можно использовать «$2», «$3» и так далее для доступа ко второму, третьему… аргументам командной строки. Вот пример:
Обратите внимание, что в переменной «$0» содержится имя самого скрипта, который запущен из командной строки. А переменная «$#» содержит количество переданных скрипту аргументов. Использование фигурных скобок необязательно только для переменных состоящих из одной цифры (с $0 по $9). Попробуйте позапускать этот скрипт с разным числом аргументов и посмотрите как он работает.
Иногда необходимо сослаться сразу на все аргументы командной строки. Для этого в bash есть специальная переменная «$@«, которая содержит все аргументы переданные скрипту разделенные пробелами. Мы будем использовать эту переменную чуть позже при рассказе о циклах со счетчиком (конструкция «for»).
Если вы раньше программировали на процедурных языках, таких как Си, Паскаль, Перл и тому подобных, вам должны быть знакомы управляющие конструкции вроде «if», «for» и другие. В bash тоже есть все эти конструкции. В следующих разделах пособия я познакомлю вас с ними и покажу чем они отличаются от подобных конструкций из других языков программирования. Если вы раньше не программировали — не волнуйтесь. Материал будет изложен подробно и дополнен примерами, так что даже новичок в программировании сможет разобраться.
Если вы раньше программировали на языке Си, то должны знать сколько требуется усилий чтобы определить какой из двух файлов был создан первым, например. А все из-за того, что в Си нет встроенных средств для такого рода сравнения. Вместо этого приходится использовать системный вызов stat() для каждого файла и затем сравнивать результат вручную. Но в bash есть встроенный механизм сравнения файлов, Поэтому узнать «доступен ли для чтения файл /tmp/myfile» настолько же просто как и узнать «превосходит ли значение переменной ‘myvar’ 4».
Привожу список наиболее часто употребляемых в bash операторов сравнения
Файлы
Строки
В следующих примерах показано как использовать оператор сравнения в конструкции «if»:
Квадратные скобки вычисляют условное выражение стоящее в них (это синоним встроенной функции bash — test). Возвращаемый результат — 1 или 0 в зависимости от того выполняется условие или нет. в скобках может стоять несколько выражений, связанных логическими операторами «и» или «или«. Подробнее на странице справки help test.
В некоторых случаях одна и та же операция сравнения может быть сделана несколькими разными способами. Обе конструкции из следующего примера функционально идентичны:
В первой конструкции из предыдущего примера использована операция арифметического сравнения, а во втором — операция сравнения строк.
В большинстве случаев, когда вы не заключаете строки и строковые переменные в двойные кавычки, это может привести к ошибке. Почему? Да потому что в строке может встретится пробел или символ табуляции, которые bash не сможет правильно обработать. Вот пример некорректного сравнения строк:
В этом примере, если значение переменной «$myvar» будет равно «foo», код будет работать как и ожидается и не печатать ничего. Но если значение переменной «$myvar» будет равно «foo bar oni», скрипт вызовет следующую ошибку:
После подстановки значения переменной, bash пытается произвести следующую операцию сравнения:
В этом случае bash не может правильно обработать сравнение строк содержащих пробелы, одна из которых не заключена в двойные кавычки. Интерпретатор думает, что в квадратных скобках слишком много аргументов. После заключения переменной в двойные кавычки, ошибка не возникает и код работает так как мы задумали. Запомните, если вы возьмете в привычку заключать в двойные кавычки все строковые аргументы и переменные, то избежите множества ошибок подобных описанной выше. Вот исправленный кусок кода:
Этот код будет работать корректно и не преподнесет нам больше никаких неприятных сюрпризов.
Замечание: Если вы хотите, чтобы подстановка значений переменных продолжала работать, заключайте их в двойные кавычки а не в одинарные. Одинарные кавычки отключают подстановку значения переменных.
Хорошо, с условными переходами разобрались, пора перейти к циклическим конструкциям. Начнем с управляющей конструкции «for«. Вот стандартный пример:
Что же именно произошло? Часть «for x» цикла «for» определяет переменную (называемую итератором) «$x», которая последовательно принимает значения «one», «two», «three», и «four» (по одному за один такт цикла). После присвоения каждого нового значения переменной «$x», выполняется тело цикла (код между словами «do» и «done»). В теле цикла мы выводим на печать значение переменной «$x». Заметим, что после слова «in» в конструкции «for» всегда стоит некий список. В данном примере мы указали четыре слова, но этот список может содержать имена файлов или даже шаблон (wildcard). В следующем примере показано как использовать шаблоны при инициализации итератора цикла:
Код этого цикла исполнится для каждого файла из /etc/ имя которого начинается с «r». Сначала bash найдет все такие файлы и заменит шаблон строкой /etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d … /etc/rsyslog.d перед тем как приступить к выполнению цикла. В теле цикла для каждого файла из списка проверяется является ли этот файл директорией при помощи оператора «-d«. Если файл оказался директорией, рядом с его называнием печатается «(dir)».
В списке инициализации итератора можно использовать несколько шаблонов одновременно и даже переменные окружения:
Bash в этом примере подставляет значение переменной и раскрывает шаблоны. А затем копирует все файлы в заданную директорию.
До этого все примеры содержали шаблоны основанные на абсолютных путях, но можно использовать и относительные:
В этом примере bash раскрывает шаблон относительно текущей рабочей директории (не той в которой находится скрипт, а той которую показывает команда «pwd»). Поиграйтесь с этим скриптом, позапускайте его из разных директорий и посмотрите на результат.
Иногда может потребоваться запустить цикл по списку аргументов из командной строки. Вот как это делается:
В этом примере мы использовали переменную «$@» о которой говорили выше.
Перед тем как приступить к разбору следующего вида циклической конструкции, научимся при помощи интерпретатора производить простые арифметические операции. Просто заключите арифметическое выражение в конструкцию «$(( ))» и bash посчитает ее значение. Вот несколько примеров:
Теперь, когда вы познакомились с вычислением арифметических выражений в shell, пришло время рассказать о циклических конструкциях «while» и «until».
«while»–цикл исполняется пока выражение в квадратных скобках истинно. Он имеет следующий формат:
В следующем примере тело цикла исполняется ровно 10 раз:
После каждого выполнения кода тела цикла переменная «myvar» увеличивается на 1. Когда значение переменной становится равным 10, условие в квадратных скобках не выполняется и цикл прерывается.
«Until»–цикл очень похож на «while»–цикл: он повторяется пока выражение в квадратных скобках ложно. Вот пример «until»–цикла по функциональности идентичного «while»–циклу из предыдущего примера:
Для экстренного выхода из «for», «while» или «until» цикла используется команда break. Для выхода из нескольких вложенных циклов — break N, где N — количество вложенных циклов.
В последнем примере: «while :» — бесконечный цикл.
Двоеточие — это команда bash которая не делает ничего но всегда завершается успехом. Переменная $? содержит статус с которым завершилась последняя команда (подробнее о специальных переменных смотри man bash). В нашем случае код отличный от 0 обозначает что при скачивании файла произошла ошибка. Как только условие в квадратных скобках выполнено, интерпретатор переходит к исполнению команды стоящей после логического и (&&). Break прерывает выполнение цикла.
Предпоследнюю строку предыдущего примера можно заменить на знакомую нам условную конструкцию «if» (помним, что в bash одно действие можно сделать несколькими разными способами):
то же самое но через условную конструкцию:
Или в одну строку
Да, конструкции можно записывать в одну строку, только нужно поставить несколько разделяющих знаков «точка с запятой». Но не стоит привыкать к такой форме записи — это усложняет читаемость кода.
Конструкция условного перехода «case» может оказаться очень полезной. Вот пример ее использования:
В этом примере сначала происходит обработка строки в переменной «$x» — «${x##*.}». Как мы помним из первой статьи, после этой операции в переменной «$x» остается только расширение файла. Затем bash сравнивает это расширение с вариантами стоящими слева от одинарных скобок «)«. Если совпадение найдено, выполняется соответствующее действие. Если совпадения не найдено, никаких действий не выполняется, но в данном конкретном коде совпадение будет всегда, потому что в последней строке стоит шаблон «*«, совпадающий с любой последовательностью символов.
В bash вы можете определять свои функции, как и в других языках программирования (C, Pascal…). Эти функции могут принимать аргументы, используя механизм очень похожий на механизм работы с аргументами командной строки. Вот пример определения простой функции:
Эта функция может быть переписана с использованием конструкции «case«. Сможете ли вы проделать это самостоятельно?
Выше мы определили функцию с именем «tarview», которая принимает один аргумент — имя тарбола. Эта функция определяет вид тарбола (без сжатия, сжатый gzip-ом или bzip2) по расширению, затем печатает этот тип и показывает содержимое архива. Если формат определить не удалось, выводится соответствующее сообщение. Вот пример вызова функции:
Как вы видите, обращение к аргументам внутри функции происходит по тем же именам как и к аргументам командной строки внутри скрипта. Переменная «$#» содержит количество переданных функции аргументов. Единственное что остается по-прежнему — переменная «$0«. Она содержит название скрипта при вызове функции из скрипта или строку «bash» при вызове функции напрямую из командной строки.
Вызвать функцию из командной строки можно следующим образом: сохраняем код функции в файл (например с названием «myfunc.txt») а затем даем следующую команду:
или что тоже самое
Эти команды строка за строкой исполняют инструкции написанные в файле в текущей командной оболочке. (Можно так же напечатать код функции строка за строкой в командной строке, но первый способ намного удобнее). После этого можем вызывать нашу функцию прямо из командной строки:
Замечание: любая функция может быть записана в файл ~/.bashrc или ~/.bash_profile, тогда вы сможете вызывать ее из командной строки в любое время при следующем логине.
Часто возникает потребность создать переменную окружения внутри функции. В большинстве компилируемых языков (например Си), когда вы создаете переменную внутри функции, она попадает в отдельное пространство имен этой функции. Например, если вы напишите функцию «my function» на C и внутри этой функции создадите переменную «x», то она никак не повлияет на переменную с тем же именем «x», созданную вне функции «myfunction».
Но в bash все по-другому. В bash, когда вы создаете переменную внутри функции, она попадает в общее пространство имен. Это значит, что она может перезаписать значение глобальной переменной с таким же именем и продолжит свое существование даже после завершения исполнения функции:
Результатом исполнения этого кода будет строка «ne two three three«, показывающая что переменная «myvar», созданная внутри функции перезаписала значение глобальной переменной «myvar» и что последнее значение итератора «x» равное «three» продолжило существование даже после завершения функции.
В этом простом примере ошибку легко заметить и устранить, переименовав переменные внутри функции. Но есть гораздо более правильное решение этой проблемы: при создании переменной можно явно указать что она является локальной при помощи инструкции «local«. Созданная таким способом внутри функции переменная будет отнесена к локальному пространству имен этой функции и не сможет никак повлиять на глобальную переменную с таким же именем. Следующий пример демонстрирует возможность создания локальной переменной:
Результатом выполнения этого кода будет строка «hello» — значение глобальной переменной «myvar» (на которую никак не повлияла локальная переменная «myvar», созданная внутри функции), а локальная переменная «x» перестает существовать после завершения функции.
Единственное условие при котором вы не должны использовать локальные переменные внутри функций — если хотите изменить значение глобальной переменной.
Вот и все. Теперь вы имеете представление о программировании в bash и можете писать свои скрипты. За более подробной информацией обращайтесь к справке man bash или к руководству Advanced Bash-Scripting Guide
Оригинал статьи— Bash by example, Part 2 (eng)
|
||
dirar
24.09.13 — 11:50 |
Подскажите пожалуйста, где ошибка в команде |
|
zva
1 — 24.09.13 — 12:04 |
netdom всю жизнь был, да и ммя юзера лучше domen\user вводить |
|
dirar
2 — 24.09.13 — 13:35 |
все равно не проходит |
|
dirar
3 — 24.09.13 — 13:36 |
Делаю так |
|
zva
4 — 24.09.13 — 13:43 |
ОС какая? |
|
dirar
5 — 24.09.13 — 13:45 |
Windows XP |
|
zva
6 — 24.09.13 — 13:47 |
netdom join comp /Domain:test.net /UserD:Domain\Administrator /PasswordD:* |
|
dirar
7 — 24.09.13 — 13:50 |
нет, к сожалению |
|
dirar
8 — 24.09.13 — 13:50 |
все время пишет, что синтаксическая ошибка. как это может быть? |
|
dirar
9 — 24.09.13 — 13:52 |
у вас проходит команда в таком виде? |
|
zva
10 — 24.09.13 — 13:53 |
имя компьютера латиницей без пробелов? |
|
zva
11 — 24.09.13 — 13:53 |
"Кроме графического интерфейса можно включить компьютер в домен с помощью командной строки. В состав операционной системы Windows XP включена утилита NETDOM, которая может добавить компьютер в домен с помощью команды: Где computer_name, domain_name и user_name нужно соответственно заменить именами добавляемого компьютера, домена и пользователя, а user_pass поменять на пароль пользователя в домене. " |
|
dirar
12 — 24.09.13 — 13:56 |
да |
|
dirar
13 — 24.09.13 — 13:58 |
dns тоже указал. и шлюз указал заранее |
|
Йохохо
14 — 24.09.13 — 14:00 |
http://technet.microsoft.com/en-us/library/cc788049.aspx |
|
dirar
15 — 24.09.13 — 14:09 |
всем спасибо, получилось в таком виде |
TurboConf 5 — расширение возможностей Конфигуратора 1С
ВНИМАНИЕ!
Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку «Обновить» в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Раньше при написании скриптов путался: где квадратные скобки, где круглые, где пробелы… Потом решил всё это дело изучить и классифицировать. И по мотивам статей с англоязычных сайтов получилось вот что:
Оператор | Назначение | К о н с т р у к ц и и | |||
---|---|---|---|---|---|
test | [ … ] | [[ … ]] | (( … )) | ||
-eq | равно | * | * | * | |
-ne | неравно | * | * | * | |
-gt | больше | * | * | * | |
-lt | меньше | * | * | * | |
-ge | больше или равно | * | * | * | |
-le | меньше или равно | * | * | * | |
= | равно | * | * | * | |
== | равно (ASCII) | * | * | * | * |
!= | неравно | * | * | * | * |
> | больше (ASCII) | * | * | ||
< | меньше (ASCII) | * | * | ||
>= | больше или равно | * | |||
<= | меньше или равно | * | |||
\> | больше (ASCII) | * | * | ||
\< | меньше (ASCII) | * | * |
В результате работы команд , , или — переменной присваеваются значения:
— если выражение верно
или
— если выражение ложно.
[shonty@~]$ test 27 -gt 5; echo $? 0[shonty@~]$ test {27} \> 5; echo $? 0 При использование с операторами , , числа более 10 необходимо заключать в фигурные скобки, иначе результат будет неверный: [shonty@~]$ test 27 \> 5; echo $? 1 Также неверный результат будет, если не ставить обратный слэш «» перед знаками неравенства. [shonty@~]$ test {27} > 5; echo $?
1
NOTE При составлении выражений необходимо проставлять пробелы. [shonty@~]$ [ 27 -gt 5 ]; echo $? 0[shonty@~]$ [ {27} \> 5 ]; echo $? 0 При использование с операторами , , числа более 10 необходимо заключать в фигурные скобки, иначе результат будет неверный (с переменными и символами ASCII работает стабильно.): [shonty@~]$ [ 27 \> 5 ]; echo $? 1
NOTE При составлении выражений необходимо проставлять пробелы. [shonty@~]$ [[ 27 -gt 5 ]]; echo $? 0 При использовании операторов и , при числовых значениях более 10 возможны ошибки. Заключение чисел в фигурные скобки ситуацию не исправляет (с переменными и символами ASCII работает стабильно). [shonty@~]$ [[ 27 > 5 ]]; echo $? 1
При составлении выражений пробелы необязательны. С символами ASCII не работает [shonty@~]$ ((27>5)); echo $? 0
Теги: Linux, Bash, Операторы сравнения, -eg, -ne, -gt, -lt, -ge, -le, test, [ … ], [[ … ]], синтаксис, значение, оператор, символы, ASCI,
Вернуться к оглавлению
В
команда выполняет системный вызов (не ) по пути, хранящемуся в и возвращает true, если этот системный вызов завершается успешно, а тип файла, возвращаемый является «регулярным».
Поэтому, если возвращает true, вы можете сказать, что файл существует и является обычным файлом или символической ссылкой, в конечном итоге разрешающей обычный файл (или, по крайней мере, это было во время ).
Однако, если он возвращает false (или если или возвращает true), существует много разных возможностей:
Короче говоря, это должно быть:
Чтобы точно знать, что файл не существует, нам понадобится системный вызов для возврата с кодом ошибки ( сообщает, что один из компонентов пути не является каталогом, это другой случай, когда мы можем сказать файл не существует по этому пути). К сожалению команда не сообщает нам об этом. Он вернет false, является ли код ошибки ENOENT, EACCESS (разрешение отклонено), ENAMETOOLONG или что-то еще.
Тест также может быть выполнен с помощью . В этом случае сообщит вам, почему сбой не удалось, хотя информация не может быть легко использована программно:
По крайней мере, говорит мне, что это не потому, что файл не существует, что он терпит неудачу. Это потому, что он не может определить, существует ли файл или нет.
Эта команда просто проигнорировала проблему.
С оболочкой вы можете запросить код ошибки с помощью специальной переменной после команды failing command и декодировать этот номер, используя специальный массив в модуле :
(остерегайтесь, что поддержка нарушена некоторыми версиями при построении с последними версиями ).
FILED UNDER : IT